给出如下熊猫数据框:
value_1 value_2
0 b a
1 a b
2 c d
3 d c
我想算一算,每对出现了多少次。换句话说,a,b等于b,a。我发现了某些情况,例如that,但在这种情况下,某些值预计只会出现在一列中。
首先,我尝试类似的操作:
pd.crosstab(df.value_1,df.value_2).replace(0,np.nan).\
stack().reset_index().rename(columns={0:'Frequency'})
通过这种方法,考虑到订单(a,b == b, a)
,我也无法删除重复项
然后,我假设使用[(a,b), (b,a), (c,d), (d,c)]
之类的列表,因此我创建了一个函数,根据其元素仅返回单对:
from itertools import combinations
def get_unique_pairs(pairs):
unique_pairs = []
for pair in combinations(pairs, 2):
if Counter(pair[0]) == Counter(pair[1]):
unordered_pair = set(list(pair[0]+pair[1]))
unique_pairs.append(unordered_pair)
return {(tuple(e)) for e in unique_pairs}
它们对[(a,b), (b,a), (c,d), (d,c)]
的输出为{(a,b), (c,d)}
但是,对于大数据框而言,这是不可行的。
最后,对于上述数据框,预期输出为:
pair frequency
0 b; a 2
1 c; d 2
答案 0 :(得分:1)
首先用numpy.sort
对每行进行排序:
df1 = pd.DataFrame(np.sort(df.values, axis=1))
然后加入并使用Series.value_counts
:
df = (df1[0] + '; ' + df1[1]).value_counts().rename_axis('pair').reset_index(name='count')
print (df)
pair count
0 a; b 2
1 c; d 2
替代GroupBy.size
:
s = (df1[0] + '; ' + df1[1])
df = s.groupby(s).size().rename_axis('pair').reset_index(name='count')