[英]Creating Pivot DataFrame using Multiple Columns in Pandas
我在下面的示例中的表单后面有一个pandas数据框:
data = {'id': [1,1,1,1,2,2,2,2,3,3,3], 'a': [-1,1,1,0,0,0,-1,1,-1,0,0], 'b': [1,0,0,-1,0,1,1,-1,-1,1,0]}
df = pd.DataFrame(data)
现在,我想要做的是创建一个数据透视表,这样对于除id之外的每个列,我将有3个与该值对应的新列。 也就是说,对于列a
,我将创建a_neg
, a_zero
和a_pos
。 同样,对于b
,我将创建b_neg
, b_zero
和b_pos
。 这些新列的值将对应于这些值在原始a
和b
列中出现的次数。 最终的数据框应如下所示:
result = {'id': [1,2,3], 'a_neg': [1, 1, 1],
'a_zero': [1, 2, 2], 'a_pos': [2, 1, 0],
'b_neg': [1, 1, 1], 'b_zero': [2,1,1], 'b_pos': [1,2,1]}
df_result = pd.DataFrame(result)
现在,要做到这一点,我可以执行以下步骤并得出我的最终答案:
by_a = df.groupby(['id', 'a']).count().reset_index().pivot('id', 'a', 'b').fillna(0).astype(int)
by_a.columns = ['a_neg', 'a_zero', 'a_pos']
by_b = df.groupby(['id', 'b']).count().reset_index().pivot('id', 'b', 'a').fillna(0).astype(int)
by_b.columns = ['b_neg', 'b_zero', 'b_pos']
df_result = by_a.join(by_b).reset_index()
但是,我认为这种方法并不是最优的,特别是如果除了a
和b
之外我有很多原始列。 是否有更短和/或更有效的解决方案来获得我想要实现的目标? 谢谢。
一个较短的解决方案,但仍然非常低效:
In [11]: df1 = df.set_index("id")
In [12]: g = df1.groupby(level=0)
In [13]: g.apply(lambda x: x.apply(lambda x: x.value_counts())).fillna(0).astype(int).unstack(1)
Out[13]:
a b
-1 0 1 -1 0 1
id
1 1 1 2 1 2 1
2 1 2 1 1 1 2
3 1 2 0 1 1 1
注意:我认为你应该针对多索引列。
我有理由相信我已经看到了一个删除apply / value_count / fillna的技巧,其中包含更清洁,更高效的东西,但此刻它让我无法...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.