Python Pandas-拆分列并包含计数

Python Pandas-拆分列并包含计数,python,pandas,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

我有以下数据帧:

            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_全文列拆分为两列,同时统计文档的出现次数

期望输出:

 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


我遵循了这个程序

这篇文章展示了几个备选方案,建议使用分类或重新索引。我尝试了以下方法:

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()
虽然这在最初的帖子中似乎效果很好,但我的计数中充满了N(见下文)。我现在读到使用reindex和Category时会发生这种情况,但我想知道为什么在最初的文章中它似乎起了作用。我怎样才能解决这个问题?有人能帮忙吗?谢谢大家!

 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

您可以将
文档id
应用于每个组,并:


或者类似于您自己的方法,如果性能是一个问题,请改为:

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

我不知道这是否是最好的方法,但这应该适合您:

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

谢谢,这个很好用。不过,有一个小问题:速度相当慢,尤其是当您拥有大量数据时。有什么办法解决这个问题吗?我会马上调查的@annika@Annika用你自己的答案。使用reindex将所有值设置为nan。你想重新命名。这应该快得多,因为id避免了任何python级别的循环。非常感谢!令人惊讶的是,一个小小的单词能带来多大的不同(reindex vs.rename)…谢谢,这非常有效-除非你有大量的数据。它很快,但是,在最后一行中,非_全文的值再次变为NaN。。。
  doc_id  is_fulltext  non_fulltext
0    id1            2             0
1    id2            1             1