У меня есть этот пандас Dataframe:

    A                             B
0   xyz                          Lena
1   NaN                          J.Brooke
2   NaN                          B.Izzie
3   NaN                          B.Rhodes
4   NaN                          J.Keith        
.....  

Я хочу сравнить значения столбца B так, что если значение строки начинается с B, то в соседней строке столбца A должно быть записано новое, и аналогично, если J то старое. Ниже то, что я ожидаю:

    A                             B
0   xyz                         Lena
1   old                         J.Brooke
2   new                         B.Izzie
3   new                         B.Rhodes
4   old                         J.Keith        
.....  

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

1
HAH 9 Июл 2019 в 09:50

3 ответа

Лучший ответ

Используйте numpy.select с Series.str.startswith если нужно установить новые значения по условиям:

m1 = df['B'].str.startswith('B')
m2 = df['B'].str.startswith('J')

При необходимости также проверьте условия цепочки пропущенных значений с помощью Series.isna :

m1 = df['B'].str.startswith('B') & df['A'].isna()
m2 = df['B'].str.startswith('J') & df['A'].isna()

df['A'] = np.select([m1, m2], ['new','old'], df['A'])
print (df)
     A         B
0  xyz      Lena
1  old  J.Brooke
2  new   B.Izzie
3  new  B.Rhodes
4  old   J.Keith

Или используйте DataFrame.loc :

df.loc[m1, 'A'] = 'new'
df.loc[m2, 'A'] = 'old'
2
jezrael 9 Июл 2019 в 06:59

Попробуйте использовать loc
Я добавил проверку .isnull (), потому что если что-то уже существует в colA, оно не будет заменено, но если вы не хотите, вы можете проигнорировать эту проверку.

import pandas 
df = pd.DataFrame(data={'colA':["xyz",np.nan,np.nan,np.nan,np.nan],
                   "colB":['Lena','J.Brooke','B.Izzie','B.Rhodes','J.Keith']})

df.loc[(df['colA'].isnull()) &(df['colB'].str.startswith("B")),"colA"] = "new"
df.loc[(df['colA'].isnull()) &(df['colB'].str.startswith("J")),"colA"] = "old"
print(df)
   colA      colB
0  xyz      Lena
1  old  J.Brooke
2  new   B.Izzie
3  new  B.Rhodes
4  old   J.Keith
2
tawab_shakeel 9 Июл 2019 в 06:57

Используя pd.Series.fillna:

df['A'].fillna(df['B'].str[0].replace({'J': 'old', 'B': 'new'}))

Выход:

     A         B
0  xyz      Lena
1  old  J.Brooke
2  new   B.Izzie
3  new  B.Rhodes
4  old   J.Keith
1
Chris 9 Июл 2019 в 07:05