我有一个看起来像这样的数据框:
start stop duration
0 1 2 1
1 3 4 2
2 2 1 2
3 4 3 0
我正在尝试构建一个字典,其中包含key =(开始,停止)对以及其持续时间的value = avg,而不管顺序如何。换句话说,(1,2)和(2,1)都算作一对(1,2)的出现。
所需的输出:dict_avg= {(1,2):1.5, (3,4):1}
实现此目标的最佳方法是什么?
答案 0 :(得分:3)
这里是通过对已排序对进行元组化的一种可能方法:
>>> grp = df[['start', 'stop']].apply(lambda x: tuple(sorted(x)), axis=1)
>>> df.groupby(grp)['duration'].mean().to_dict()
{(1, 2): 1.5, (3, 4): 1.0}
作为免责声明,我几乎可以保证它会比这里给出的NumPy-sort慢得多,因为在lambda
中使用.apply()
(并且需要使用sorted()
+ { {1}}构造函数)接受Python空间中的每个调用,而不是像您理想地通过Pandas / NumPy那样在Cython / C中完成它。
答案 1 :(得分:3)
使用frozenset
而不是整洁,如果您要寻找有效的方式检查link
df.groupby(df[['start','stop']].apply(frozenset,1).map(tuple)).duration.mean().to_dict()
Out[1048]: {(1, 2): 1.5, (3, 4): 1.0}
答案 2 :(得分:3)
这也是一种方式:
# sort data based on first two columns
df.iloc[:,:2].values.sort()
# create the dict of mean
df.groupby(['start','stop'])['duration'].mean().to_dict()
{(1, 2): 1.5, (3, 4): 1.0}
答案 3 :(得分:3)
defaultdict
from collections import defaultdict
m = defaultdict(list)
for *t, d in zip(*map(df.get, df)):
m[tuple({*t})].append(d)
{k: sum(v) / len(v) for k, v in m.items()}
{(1, 2): 1.5, (3, 4): 1.0}