【问题标题】:No change in the original values of a dataframe数据框的原始值没有变化
【发布时间】:2019-04-28 16:22:24
【问题描述】:

我有一个示例数据框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 为 41。基本上,我必须获得以下内容:

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 的值时,根本没有没有修改。我猜我正在处理数据帧的副本而不是实际的数据帧,但我不知道如何解决这个问题。

【问题讨论】:

    标签: python pandas dataframe lambda pandas-groupby


    【解决方案1】:

    问题是您在循环中创建了一个新变量,其中包含数据的浅表副本并对其进行修改。除非您自己使用df.loc 进行更改,否则不会实际写入对原始数据帧的更改。另一个更好的选择是将其向量化,移除循环。

    您需要groupbytransform

    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']
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-10
      • 2019-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多