Pandas: 如何以两种方式获取两列值的唯一组合?
Pandas: How to get Unique combinations of two column values in either ways?
我想知道如果值是相似的组合,我们如何才能得到两个列值的唯一组合。下面是数据框
我尝试使用以下代码,但我的预期输出不同
df.groupby(['column1', 'column2'], as_index = 假).agg({'expense' : 'sum'})
这是 的变体,但一个重要的区别是您似乎并不关心 column1
或 column2
的顺序。在我分享解决方案之前,这是伪代码:
- 创建一个
id
列,我们可以使用它来查找 column1
和 column2
的集合相同的行
- 将链接 post 中的方法应用到
id
。
- 根据 id 删除重复项
这是我对数据的手动转录。以后请以文本形式提供示例数据,而不是屏幕截图。
column1,column2,salary
ram,shyam,100
sita,geeta,500
geeta,sita,300
shyam,ram,600
sohan,mohan,200
mohan,sohan,400
这是代码
>>> import pandas as pd
>>> df = pd.read_csv('data.csv')
>>> hash_func = lambda n: hash("-".join(sorted(n)))
>>> df['id'] = df[['column1','column2']].apply(hash_func, axis=1)
>>> df
column1 column2 salary id
0 ram shyam 100 -1387604912582040812
1 sita geeta 500 9030593041392264307
2 geeta sita 300 9030593041392264307
3 shyam ram 600 -1387604912582040812
4 sohan mohan 200 6327789560655124249
5 mohan sohan 400 6327789560655124249
>>> df['expense'] = df.groupby('id')['salary'].transform('sum')
>>> df
column1 column2 salary id expense
0 ram shyam 100 7227562739062788100 700
1 sita geeta 500 6328366926112663723 800
2 geeta sita 300 6328366926112663723 800
3 shyam ram 600 7227562739062788100 700
4 sohan mohan 200 -3239226935758438599 600
5 mohan sohan 400 -3239226935758438599 600
>>> df = df.drop_duplicates(subset=['id'])
>>> df
column1 column2 salary id expense
0 ram shyam 100 7227562739062788100 700
1 sita geeta 500 6328366926112663723 800
4 sohan mohan 200 -3239226935758438599 600
>>> df = df.drop(columns=['id','salary']) # some extra cleanup
>>> df
column1 column2 expense
0 ram shyam 700
1 sita geeta 800
4 sohan mohan 600
我遵循了这些步骤
df['pairs'] = df['col1'] + '-' + df['col2']
然后将 foo
函数应用于此列
这个函数的想法是获取 pairs
列数据并根据对中每个元素的第一个字符对其进行排序。
例如输入是 ram-shyam
或 ram-shaym
我们将得到输出 ram-shyam
这是foo
函数-
def foo(s):
lst_s = s.split('-')
temp = {}
for idx, name in enumerate(lst_s):
temp[idx]= name[0]
temp = dict(sorted(temp.items(), key=lambda item: item[1]))
final = []
for key in temp.keys():
final.append(lst_s[key])
return '-'.join(final)
现在在 pairs
列上应用此函数
df['unique-pair'] = df['pairs'].apply(foo)
输出现在看起来像这样 -
col1 col2 salary unique-pair pairs
0 ram shyam 100 ram-shyam ram-shyam
1 sita gita 500 gita-sita sita-gita
2 gita sita 300 gita-sita gita-sita
3 shyam ram 600 ram-shyam shyam-ram
4 sohan mohan 200 mohan-sohan sohan-mohan
5 mohan sohan 400 mohan-sohan mohan-sohan
现在您可以按
分组
df.groupby(['unique-pair']).agg({'salary':sum})
最终输出为-
salary
unique-pair
gita-sita 800
mohan-sohan 600
ram-shyam 700
您可以对第一列和第二列进行排序,以便 a,b
和 b,a
在 groupby 中被视为相同。
现在,由于 sort()
已弃用,我们可以使用 numpy 排序和 re-create 新数据框。
假设以下 csv_file:
column1,column2,salary
a,b,1
c,b,3
b,a,10
b,c,30
d,e,99
我们可以这样做:
import pandas as pd
import numpy as np
df = pd.read_csv("csvfile.csv",)
print("Original:\n ",df.head())
print ("\nGrouped sum:\n")
print ((pd.concat([pd.DataFrame(np.sort(df[df.columns[:2]], axis=1), columns=df.columns[:2]),\
df["salary"]], axis=1)).reset_index(drop=True, inplace=False).groupby\
(["column1", "column2"]).sum())
输出如下图:
Original:
column1 column2 salary
0 a b 1
1 c b 3
2 b a 10
3 b c 30
4 d e 99
Grouped sum:
salary
column1 column2
a b 11
b c 33
d e 99
我想知道如果值是相似的组合,我们如何才能得到两个列值的唯一组合。下面是数据框
我尝试使用以下代码,但我的预期输出不同
df.groupby(['column1', 'column2'], as_index = 假).agg({'expense' : 'sum'})
这是 column1
或 column2
的顺序。在我分享解决方案之前,这是伪代码:
- 创建一个
id
列,我们可以使用它来查找column1
和column2
的集合相同的行 - 将链接 post 中的方法应用到
id
。 - 根据 id 删除重复项
这是我对数据的手动转录。以后请以文本形式提供示例数据,而不是屏幕截图。
column1,column2,salary
ram,shyam,100
sita,geeta,500
geeta,sita,300
shyam,ram,600
sohan,mohan,200
mohan,sohan,400
这是代码
>>> import pandas as pd
>>> df = pd.read_csv('data.csv')
>>> hash_func = lambda n: hash("-".join(sorted(n)))
>>> df['id'] = df[['column1','column2']].apply(hash_func, axis=1)
>>> df
column1 column2 salary id
0 ram shyam 100 -1387604912582040812
1 sita geeta 500 9030593041392264307
2 geeta sita 300 9030593041392264307
3 shyam ram 600 -1387604912582040812
4 sohan mohan 200 6327789560655124249
5 mohan sohan 400 6327789560655124249
>>> df['expense'] = df.groupby('id')['salary'].transform('sum')
>>> df
column1 column2 salary id expense
0 ram shyam 100 7227562739062788100 700
1 sita geeta 500 6328366926112663723 800
2 geeta sita 300 6328366926112663723 800
3 shyam ram 600 7227562739062788100 700
4 sohan mohan 200 -3239226935758438599 600
5 mohan sohan 400 -3239226935758438599 600
>>> df = df.drop_duplicates(subset=['id'])
>>> df
column1 column2 salary id expense
0 ram shyam 100 7227562739062788100 700
1 sita geeta 500 6328366926112663723 800
4 sohan mohan 200 -3239226935758438599 600
>>> df = df.drop(columns=['id','salary']) # some extra cleanup
>>> df
column1 column2 expense
0 ram shyam 700
1 sita geeta 800
4 sohan mohan 600
我遵循了这些步骤
df['pairs'] = df['col1'] + '-' + df['col2']
然后将 foo
函数应用于此列
这个函数的想法是获取 pairs
列数据并根据对中每个元素的第一个字符对其进行排序。
例如输入是 ram-shyam
或 ram-shaym
我们将得到输出 ram-shyam
这是foo
函数-
def foo(s):
lst_s = s.split('-')
temp = {}
for idx, name in enumerate(lst_s):
temp[idx]= name[0]
temp = dict(sorted(temp.items(), key=lambda item: item[1]))
final = []
for key in temp.keys():
final.append(lst_s[key])
return '-'.join(final)
现在在 pairs
列上应用此函数
df['unique-pair'] = df['pairs'].apply(foo)
输出现在看起来像这样 -
col1 col2 salary unique-pair pairs
0 ram shyam 100 ram-shyam ram-shyam
1 sita gita 500 gita-sita sita-gita
2 gita sita 300 gita-sita gita-sita
3 shyam ram 600 ram-shyam shyam-ram
4 sohan mohan 200 mohan-sohan sohan-mohan
5 mohan sohan 400 mohan-sohan mohan-sohan
现在您可以按
分组df.groupby(['unique-pair']).agg({'salary':sum})
最终输出为-
salary
unique-pair
gita-sita 800
mohan-sohan 600
ram-shyam 700
您可以对第一列和第二列进行排序,以便 a,b
和 b,a
在 groupby 中被视为相同。
现在,由于 sort()
已弃用,我们可以使用 numpy 排序和 re-create 新数据框。
假设以下 csv_file:
column1,column2,salary
a,b,1
c,b,3
b,a,10
b,c,30
d,e,99
我们可以这样做:
import pandas as pd
import numpy as np
df = pd.read_csv("csvfile.csv",)
print("Original:\n ",df.head())
print ("\nGrouped sum:\n")
print ((pd.concat([pd.DataFrame(np.sort(df[df.columns[:2]], axis=1), columns=df.columns[:2]),\
df["salary"]], axis=1)).reset_index(drop=True, inplace=False).groupby\
(["column1", "column2"]).sum())
输出如下图:
Original:
column1 column2 salary
0 a b 1
1 c b 3
2 b a 10
3 b c 30
4 d e 99
Grouped sum:
salary
column1 column2
a b 11
b c 33
d e 99