熊猫-拆分列并包含计数

时间:2019-03-27 10:55:26

标签: python pandas

我有以下数据框:

            doc_id  is_fulltext
1243      dok:1            1
3310      dok:1            1
4370      dok:1            1
14403  dok:1020            1
17252  dok:1020            1
15977  dok:1020            0
16480  dok:1020            1
16252  dok:1020            1
468     dok:103            1
128    dok:1030            0
1673   dok:1038            1

我想将is_fulltext列分为两列,并同时计算文档的出现次数。

所需的输出:

 doc_id                 fulltext  non-fulltext
0           dok:1        3          0
1           dok:1020     4          1
2           dok:103      1          0
3           dok:1030     0          1
4           dok:1038     1          0


我遵循了Pandas - Create columns from column value, and fill with count

的程序

该帖子显示了几种选择,建议分类或重新索引。我尝试了以下方法:

cats = ['fulltext', 'non_fulltext']
df_sorted['is_fulltext'] = pd.Categorical(df_sorted['is_fulltext'], categories=cats)
new_df = df_sorted.groupby(['doc_id', 'is_fulltext']).size().unstack(fill_value=0)

在这里我遇到了ValueError:

ValueError: Length of passed values is 17446, index implies 0

然后我尝试了这种方法


cats = ['fulltext', 'non_fulltext']
new_df = df_sorted.groupby(['doc_id','is_fulltext']).size().unstack(fill_value=0).reindex(columns=cats).reset_index()

虽然这在原始帖子中似乎工作得很好,但我的计数充满了NAN(请参见下文)。我现在读到,使用reindex和categorical时会发生这种情况,但是我想知道为什么它似乎在原始文章中起作用了。我该如何解决呢?有人可以帮忙吗?谢谢!

 doc_id                         fulltext  non-fulltext
0           dok:1                NaN          NaN
1           dok:1020             NaN          NaN
2           dok:103              NaN          NaN
3           dok:1030             NaN          NaN
4           dok:1038             NaN          NaN

2 个答案:

答案 0 :(得分:2)

您可以GroupBy doc_id,将pd.value_counts应用于每个组,unstack

(df.groupby('doc_id').is_fulltext.apply(pd.value_counts)
                                 .unstack()
                                 .fillna(0)
                                 .rename(columns={0:'non-fulltext', 1:'fulltext'})
                                 .reset_index())

    doc_id      non-fulltext  fulltext
0     dok:1           0.0       3.0
1  dok:1020           1.0       4.0
2   dok:103           0.0       1.0
3  dok:1030           1.0       0.0
4  dok:1038           0.0       1.0

或者与您自己的方法类似,如果性能存在问题,请改为:

df.groupby(['doc_id','is_fulltext']).size()
                                    .unstack(fill_value=0)
                                    .rename(columns={0:'fulltext',1:'non_fulltext'})
                                    .reset_index()

is_fulltext    doc_id  fulltext  non_fulltext
0               dok:1         0             3
1            dok:1020         1             4
2             dok:103         0             1
3            dok:1030         1             0
4            dok:1038         0             1

答案 1 :(得分:0)

我不知道这是否是最好的方法,但这应该对您有用:

import pandas as pd
df = pd.DataFrame({"doc_id":["id1", "id2", "id1", "id2"], 
                   "is_fulltext":[1, 0, 1, 1]})
df_grouped = df.groupby("doc_id").sum().reset_index()
df_grouped["non_fulltext"] = df.groupby("doc_id").count().reset_index()["is_fulltext"] - df_grouped["is_fulltext"]
df_grouped 

输出为:

  doc_id  is_fulltext  non_fulltext
0    id1            2             0
1    id2            1             1