我有一个示例数据帧df
如下-
A B
1 41
2 42
3 43
1 46
2 47
3 48
1 51
2 52
3 53
我当前的目标是,对于列A的特定值,用第一次出现的值替换列B的所有值。例如,对于A = 1,B = 41是第一个对应的值。因此,对于B列,我必须用A = 1替换所有其他行。基本上,我必须获得以下内容:
A B
1 41
2 42
3 43
1 41
2 42
3 43
1 41
2 42
3 43
我尝试进行以下操作:
方法1-
a = df.A.unique()
for i in a:
x = df.loc[df['A'] == i]
x['B'] = x['B'].iloc[0]
print(x)
在打印x
时,这给了我所需的输出
A B
0 1 41
3 1 41
6 1 41
A B
1 2 42
4 2 42
7 2 42
A B
2 3 43
5 3 43
8 3 43
但是当我再次检查数据框df
时,值完全没有变化。
我还尝试了以下替代方法-
方法-2
def custom_function(df):
x = df['B'].iloc[0]
df['A'] = df['A']
df.loc[:,['B']] = x
return df['A']
for key, item in df.groupby('A'):
item.apply(lambda x: custom_function(item))
print(item)
在打印item
时,这也给了我所需的输出--
A B
0 1 41
3 1 41
6 1 41
A B
1 2 42
4 2 42
7 2 42
A B
2 3 43
5 3 43
8 3 43
但是当我检查数据帧df
的值时,根本没有任何修改。我猜想我正在处理数据框的副本,而不是实际的数据框,但是我对如何解决此问题感到困惑。
答案 0 :(得分:1)
问题在于您正在使用浅层数据副本在循环内创建一个新变量并对其进行修改。除非您自己使用df.loc
进行更改,否则实际上不会写入对原始数据帧的更改。另一个更好的选择是将其向量化,从而消除循环。
您将需要groupby
和transform
:
df = df.assign(B=df.groupby('A').B.transform('first')).sort_values('A')
print(df)
A B
0 1 41
3 1 41
6 1 41
1 2 42
4 2 42
7 2 42
2 3 43
5 3 43
8 3 43
仅出于您的理解,这是修复循环的方法:
for a in df.A.unique():
m = df['A'] == a
df.loc[m, 'B'] = df.at[m.idxmax(), 'B']