如何使用多个DataFrame列应用复杂函数?

时间:2018-01-29 21:34:23

标签: python-2.7 pandas

我尝试在DataFrame上执行计算,该计算会添加一个新列,其中包含的值是同一DataFrame的另一列中的行总和。我找到了提供apply()多个DataFrame列的其他示例,但我还没有看到一个示例执行查询以在另一列中查找唯一值集。以下代码将设置一个极为简化的示例:

import pandas as pd

columns = ('Place_1','Place_2','Distance','Population_of_Place_2','SUM')
data = [('Alpha','Beta',5,324,0),
        ('Alpha','Gamma',9,42,324),
        ('Alpha','Delta',10,77,366),
        ('Beta','Alpha',5,101,0),
        ('Beta','Gamma',6,42,101),
        ('Beta','Delta',11,77,143),
        ('Gamma','Alpha',9,101,401),
        ('Gamma','Beta',6,324,0),
        ('Gamma','Delta',7,77,324),
        ('Delta','Alpha',10,101,42),
        ('Delta','Beta',11,324,143),
        ('Delta','Gamma',7,42,0)]

df = pd.DataFrame.from_records(data=data, columns=columns)


   Place_1 Place_2  Distance  Population_of_Place_2  SUM
0    Alpha    Beta         5                    324    0
1    Alpha   Gamma         9                     42  324
2    Alpha   Delta        10                     77  366
3     Beta   Alpha         5                    101    0
4     Beta   Gamma         6                     42  101
5     Beta   Delta        11                     77  143
6    Gamma   Alpha         9                    101  401
7    Gamma    Beta         6                    324    0
8    Gamma   Delta         7                     77  324
9    Delta   Alpha        10                    101   42
10   Delta    Beta        11                    324  143
11   Delta   Gamma         7                     42    0

我尝试生成的新专栏是 SUM 。考虑到这是一个逐行计算,我需要找到距离值小于当前行的所有行,然后计算这些行的总体总和(即 Population_of_Place_2 )。

例如,前三行告诉我们没有比 Beta 更接近 Alpha 的位置。因此第一行的 SUM 值为0.

然而,当我们评估第二行时,我们应该发现位置 Beta Gamma 更近:距离值分别为5对9。所以第二行 SUM 的值只是 Beta 的总体,因为 Delta 还有更进一步的方式(距离 > == 10)。

最后,当我们评估第三行时,现在有两个位置( Alpha Gamma )更接近,所以我们的人口 SUM 与他们的人口总和。

我的预感是,我可以通过巧妙地使用apply()和/或groupby()来实现这一点 - 我已经尝试过了 - 但到目前为止我还没有运气。我想我最大的希望是有人会告诉我,如果能够在大熊猫中干净利落地完成这项工作,那么我就可以继续做一些笨重的事了。

1 个答案:

答案 0 :(得分:1)

首先,按距离对数据框使用sort_values,使用groupby,然后使用shift忽略该组的第一个值,cumsum,最后fillna零。如果您需要转换回整数,请使用astype

df['SUM'] = (df.sort_values(['Distance'])
               .groupby('Place_1')['Population_of_Place_2']
               .transform(lambda x: x.shift(1).cumsum())
               .fillna(0)).astype(int)

输出:

   Place_1 Place_2  Distance  Population_of_Place_2  SUM
0    Alpha    Beta         5                    324    0
1    Alpha   Gamma         9                     42  324
2    Alpha   Delta        10                     77  366
3     Beta   Alpha         5                    101    0
4     Beta   Gamma         6                     42  101
5     Beta   Delta        11                     77  143
6    Gamma   Alpha         9                    101  401
7    Gamma    Beta         6                    324    0
8    Gamma   Delta         7                     77  324
9    Delta   Alpha        10                    101   42
10   Delta    Beta        11                    324  143
11   Delta   Gamma         7                     42    0