pandas Python Dataframe 中相关行的值总和

mctunoxg  于 2023-01-01  发布在  Python
关注(0)|答案(1)|浏览(137)

我有一个数据框,其中一些行有一个ID和一个相关ID。在下面的示例中,a1a2相关(假设是同一个人),而bc没有任何相关行。

import pandas as pd

test = pd.DataFrame(
    [['a1', 1, 'a2'],
     ['a1', 2, 'a2'],
     ['a1', 3, 'a2'],
     ['a2', 4, 'a1'],
     ['a2', 5, 'a1'],
     ['b',  6,     ],
     ['c',  7,     ]],
    columns=['ID1', 'Value', 'ID2']
)

test
  ID1  Value   ID2
0  a1      1    a2
1  a1      2    a2
2  a1      3    a2
3  a2      4    a1
4  a2      5    a1
5   b      6  None
6   c      7  None

我需要实现的是添加一个列,该列包含相关行的所有值的总和。在这种情况下,所需的输出应该如下所示。请问有什么方法可以得到这个结果?
| 识别码1|价值|识别码2|按ID1和ID2分组|
| - ------| - ------| - ------| - ------|
| a1| 1个|a2|十五|
| a1|第二章|a2|十五|
| a1|三个|a2|十五|
| a2|四个|a1|十五|
| a2|五个|a1|十五|
| b.人口基金|六个||六个|
| (c)秘书长的报告|七||七|
注意,我学习了使用group by来获得ID1的和(从这个问题);但不能同时用于"ID1"和"ID2"。

test['Group by ID1'] = test.groupby("ID1")["Value"].transform("sum")
test

  ID1  Value   ID2  Group by ID1
0  a1      1    a2             6
1  a1      2    a2             6
2  a1      3    a2             6
3  a2      4    a1             9
4  a2      5    a1             9
5   b      6  None             6
6   c      7  None             7
    • 更新**

我想我仍然可以使用for循环来完成下面的工作。但是我想知道是否有其他非循环的方法。谢谢。

bottle = pd.DataFrame().reindex_like(test)
bottle['ID1'] = test['ID1']
bottle['ID2'] = test['ID2']

for index, row in bottle.iterrows():
    bottle.loc[index, "Value"] = test[test['ID1'] == row['ID1']]['Value'].sum() + \
    test[test['ID1'] == row['ID2']]['Value'].sum()

print(bottle)

  ID1  Value   ID2
0  a1   15.0    a2
1  a1   15.0    a2
2  a1   15.0    a2
3  a2   15.0    a1
4  a2   15.0    a1
5   b    6.0  None
6   c    7.0  None
y1aodyip

y1aodyip1#

一个可能的解决方案是将ID1ID2中的对排序,使得它们总是以相同的顺序出现。
交换ID:

s = df['ID1'] > df['ID2']
df.loc[s, ['ID1', 'ID2']] = df.loc[s, ['ID2', 'ID1']].values
print(df)
>>> ID1 Value ID2
0   a1  1   a2
1   a1  2   a2
2   a1  3   a2
3   a1  4   a2
4   a1  5   a2
5   b   6   None
6   c   7   None

然后我们可以做一个简单的groupby:

df['RSUM'] = df.groupby(['ID1', 'ID2'], dropna=False)['Value'].transform("sum")
print(df)
>>> ID1 Value ID2 RSUM
0   a1  1   a2  15
1   a1  2   a2  15
2   a1  3   a2  15
3   a1  4   a2  15
4   a1  5   a2  15
5   b   6   None    6
6   c   7   None    7

注意dropna=False不丢弃没有配对的ID。如果不想永久交换ID,可以只创建一个临时 Dataframe 。

相关问题