Панды: Перебирайте строки, чтобы обновить значение столбца

#python #pandas #dataframe #csv

Вопрос:

Вот пример фрейма данных, который выглядит так:

 >>> df
  point    x      y
0  0.1   NaN    NaN
1  0.2   NaN    NaN
2  0.3   5.0    NaN
3  0.4   NaN    NaN
4  0.5   NaN    1.0
5  0.6   NaN    NaN
6  0.7   1.0    1.0
7  0.8   NaN    NaN
8  0.9   NaN    NaN
9  1.1   NaN    NaN
10 1.2   NaN    NaN
11 1.3   NaN    NaN
12 1.4   NaN    2.0
13 1.5   NaN    NaN
14 1.6   NaN    NaN
15 1.7   NaN    NaN
16 0.1   NaN    NaN
17 0.2   NaN    NaN
18 0.3   NaN    NaN
19 0.4   NaN    NaN
20 0.5   NaN    NaN
21 0.6   2.0    NaN
22 0.7   NaN    NaN
23 1.1   NaN    NaN
 

Из этого фрейма данных я хочу обновить point значение. Состояние, когда x или y не NaN ближайший ценности point будут заменены на предыдущие point значения, после этого следующая точка, значение должно быть переиндексирован(цикл, к .1 .6). например. в индексной строке(2) если point=0.3, x=5.0 так, следующее point значение должно быть 0.3 вместо 0.4, а затем в индексной строке(4) точки=0.5 будет заменен на 0,4(далее рекурсивно)

ВЫВОД, который я хочу:

   point    x      y
0  0.1   NaN    NaN
1  0.2   NaN    NaN
2  0.3   5.0    NaN
3  0.3   NaN    NaN
4  0.4   NaN    1.0
5  0.4   NaN    NaN
6  0.5   1.0    1.0
7  0.5   NaN    NaN
8  0.6   NaN    NaN
9  1.1   NaN    NaN
10 1.2   NaN    NaN
11 1.3   NaN    NaN
12 1.4   NaN    2.0
13 1.4   NaN    NaN
14 1.5   NaN    NaN
15 1.6   NaN    NaN
16 0.1   NaN    NaN
17 0.2   NaN    NaN
18 0.3   NaN    NaN
19 0.4   NaN    NaN
20 0.5   NaN    NaN
21 0.6   2.0    NaN
22 0.6   NaN    NaN
23 1.1   NaN    NaN
 

Код, который я пробовал:

 import pandas as pd
df = pd.read_csv("data.csv")
df['point'] = df.groupby() #Don't know how should I approach
 

Комментарии:

1. Теперь проблема ясна и коротка ( 1 за это).

2. Ваш цикл-это чередование 0. и 1.?

3. Например, цикл: 0.1-0.6 , 1.1-1.6 , 2.1-2.6 и так далее. В промежутке между .1-.6 циклами любое значение может появляться несколько раз подряд, но за индексом следует следовать, например 0.1 0.1 0.2 0.3 0.4 0.4 0.5 0.5 0.6 1.1 …

Ответ №1:

Ты можешь попробовать это:

 mask = df[['x', 'y']].any(axis=1).shift(1, fill_value=False)
point = df['point'].astype(int)
group = point.sub(point.shift(1)).ne(0).cumsum()

df['point'] = df['point'].sub(mask.groupby(group).cumsum().div(10))
 
 >>> df
    point    x    y
0     0.1  NaN  NaN
1     0.2  NaN  NaN
2     0.3  5.0  NaN
3     0.3  NaN  NaN
4     0.4  NaN  1.0
5     0.4  NaN  NaN
6     0.5  1.0  1.0
7     0.5  NaN  NaN
8     0.6  NaN  NaN
9     1.1  NaN  NaN
10    1.2  NaN  NaN
11    1.3  NaN  NaN
12    1.4  NaN  2.0
13    1.4  NaN  NaN
14    1.5  NaN  NaN
15    1.6  NaN  NaN
16    0.1  NaN  NaN
17    0.2  NaN  NaN
18    0.3  NaN  NaN
19    0.4  NaN  NaN
20    0.5  NaN  NaN
21    0.6  2.0  NaN
22    0.6  NaN  NaN
23    1.1  NaN  NaN
 

Комментарии:

1. Спасибо за это. Но все равно это не решило мою проблему. point значение также должно быть переиндексировано. Например, в индексе строки(4) point должно быть 0,4 вместо 0,5. Существует цикл _.1 to _.6 , которому необходимо следовать. Пожалуйста, взгляните на мой образец вывода.

2. @pythonnoob. Я думаю, что я сделал это :-). Это оказалось не так просто, как ожидалось, но теперь ваш первый шаг сделан! Я надеюсь, что вы примете и поддержите, если это соответствует вашим потребностям 😛

Ответ №2:

Поэтому я кое-что попробовал. Сначала создал какой-то фрейм данных для себя. Я пытался следовать вашему тексту (это немного сбивало с толку меня, не являющегося носителем языка). Я кое-что написал. Это не очень общий подход, но он должен работать для вашего случая, и с помощью этой идеи, я думаю, вы сможете решить проблемы.

 import numpy as np
import pandas as pd
df = np.zeros((8, 3))
f = np.random.randint(8, size=8)

df[:, 0] = f
df[:, 1:] = np.nan
df[1, 1] = 5
df[3, 1:] = 4

df = pd.DataFrame(df)
print(df)

for i in range(len(df)):
    if (df.iloc[i, 1:].notnull()).any()amp;(df.iloc[i, 1:].isnull()).any():
        print(i)
        df[0][i 1] = df[0][i]
 

Комментарии:

1. Извините, я не могу связать эти коды с моей проблемой.

2. Пока цикл не завершится, он просто создает некоторый фрейм данных, так как у меня нет ваших данных. Цикл выполняет вашу идею.