熊猫 - 基于另一列的交叉参考计算新值

问题描述 投票:0回答:2

我正在尝试计算其值与另一列交叉引用的列中的新值。

>>> import pandas as pd
>>> df = pd.DataFrame( {"A":[0., 100., 80., 40., 0., 60.], 
                        "B":[12,  12,   3,  19,  3,  19]} )
>>> df
       A   B
0    0.0  12
1  100.0  12
2   80.0   3
3   40.0  19
4    0.0   3
5   60.0  19

我想在列A中找到0的所有值,找出列B中的相应值,然后根据某个函数更改具有相同列B值的所有列A值。例如,在上面的例子中,我想将A列的前两个值df.A[0]df.A[1]分别改为0.5和99.5,因为df.A[0]为0.并且它在B列中具有相同的值df.B[0] = 12作为df.B[1] = 12

df
      A   B
0   0.5  12
1  99.5  12
2  79.5   3
3  40.0  19
4   0.5   3
5  60.0  19

我尝试链接loc,aggregate,groupby和mask功能,但我没有成功。通过for循环是唯一的方法吗?


编辑:更广泛的例子,以更好地说明意图。

python pandas method-chaining cross-reference
2个回答
1
投票

这将有效:

import pandas as pd

df = pd.DataFrame( {"A":[0., 100., 40., 60.], "B":[12, 12, 19, 19]} )

def f(series):
    return (series + 0.5).where(series == 0, series - 0.5)

B_value = df.loc[df['A'] == 0, 'B'][0]
df.loc[df['B'] == B_value, 'A'] = df.loc[df['B'] == B_value, 'A'].transform(f)

print(df)

输出:

      A   B
0   0.5  12
1  99.5  12
2  40.0  19
3  60.0  19

你可以将任意函数传递给transform

可能有一种更清洁的方法来做到这一点;它让我感到有点凌乱。


0
投票

我找到了一个有效的解决方案,尽管可能不是最佳的。我链接groupby,过滤和转换以获得所需的系列,然后替换原始数据帧中的结果。

import pandas as pd
df = pd.DataFrame( {"A":[0., 100., 80., 40., 0., 60.], 
                    "B":[12,  12,   3,  19,  3,  19]} )
u = ( df.groupby(by="B",  sort=False)
         .filter(lambda x: x.A.min() == 0, dropna=False)
         .A.transform( lambda x: (x+0.5).where(x == 0, x - 0.5) ) 
    )
df.loc[pd.notnull(u), "A"] = u

给出以下结果

print("\ninitial df\n",df,"\n\nintermediate series\n",u,"\n\nfinal result",df)

initial df
        A   B
0    0.0  12
1  100.0  12
2   80.0   3
3   40.0  19
4    0.0   3
5   60.0  19

intermediate series
 0     0.5
1    99.5
2    79.5
3     NaN
4     0.5
5     NaN
Name: A, dtype: float64

final result       A   B
0   0.5  12
1  99.5  12
2  79.5   3
3  40.0  19
4   0.5   3
5  60.0  19
© www.soinside.com 2019 - 2024. All rights reserved.