Я пытаюсь shift
значения в pandas df
. В частности, rows
которые соответствуют определенному value
. Для df
ниже я хочу shift
row
влево, когда указанное выше значение равно == 'X'
.
d = ({
'A' : ['Foo','','Foo',''],
'B' : ['X','Bar','X','Bar'],
'C' : ['','Y','','Y'],
})
df = pd.DataFrame(data=d)
Из:
A B C
0 Foo X
1 Bar Y
2 Foo X
3 Bar Y
Я пробовал это:
b = ['X']
x = df.B=='X'
df.loc[x, b] = df.loc[x, b].apply(lambda x: x.shift(-1), axis=1)
Предполагаемый результат:
A B C
0 Foo X
1 Bar Y
2 Foo X
3 Bar Y
Хотя эти strings
идентичны, мой набор данных меняется. Foo
будет таким же, но string
, следующая за X
будет отличаться. Поэтому я не могу просто выбрать " Bar
и shift
row
влево. Мне нужно что-то, что найдет row
ниже X
и сдвинется влево
IIUC
s = (df == 'X').any(1)
idx_to_change = s[s].index+1
df.loc[idx_to_change,:] = df.loc[idx_to_change].shift(-1,axis=1)
df.fillna('')
A B C
0 Foo X
1 Bar Y
2 Foo X
3 Bar Y
Ты можешь сделать
df.replace('',np.nan).apply(lambda x: sorted(x, key=pd.isnull), 1).fillna('')
Out[538]:
A B C
0 Foo X
1 Bar Y
2 Foo X
3 Bar Y
Если вы просто хотите избавиться от пустых значений, вы можете использовать понимание списка, а затем pd.DataFrame
конструктор pd.DataFrame
:
res = pd.DataFrame([list(filter(None, row)) for row in df.values.tolist()],
columns=df.columns[:2])
print(res)
A B
0 Foo X
1 Bar Y
2 Foo X
3 Bar Y
X
только в столбце B?