【问题标题】:Filter data with groupby in pandas在 pandas 中使用 groupby 过滤数据
【发布时间】:2017-09-04 17:10:15
【问题描述】:

我有一个 DataFrame,其中包含以下数据。每行代表一个词出现在电视剧的每一集中。如果一个单词在一集中出现 3 次,则 pandas 数据框有 3 行。现在我需要过滤一个单词列表,这样我应该只得到出现超过或等于 2 次的单词。我可以通过groupby 做到这一点,但如果一个词出现 2 次(或者说 3,4 或 5)次,我需要两行(3、4 或 5)行。

通过 groupby,我只会获得唯一的条目和计数,但我需要条目重复出现在对话中的次数。有没有一种方法可以做到这一点?

       dialogue  episode
0         music        1
1   corrections        1
2       somnath        1
3         yadav        5
4          join        2
5     instagram        1
6          wind        2
7         music        1
8    whimpering        2
9         music        1
10         wind        3

所以理想情况下我应该得到,

   dialogue  episode
0     music        1
6      wind        2
7     music        1
9     music        1
10     wind        3

因为只有这两个词出现超过或等于 2 次。

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    你可以使用groupby的filter

    In [11]: df.groupby("dialogue").filter(lambda x: len(x) > 1)
    Out[11]:
       dialogue  episode
    0     music        1
    6      wind        2
    7     music        1
    9     music        1
    10     wind        3
    

    【讨论】:

    • 我更喜欢这个解决方案
    【解决方案2】:

    更新问题的答案:

    In [208]: df.groupby('dialogue')['episode'].transform('size') >= 3
    Out[208]:
    0      True
    1     False
    2     False
    3     False
    4     False
    5     False
    6     False
    7      True
    8     False
    9      True
    10    False
    dtype: bool
    
    In [209]: df[df.groupby('dialogue')['episode'].transform('size') >= 3]
    Out[209]:
      dialogue  episode
    0    music        1
    7    music        1
    9    music        1
    

    原问题的答案:

    你可以使用duplicated()方法:

    In [202]: df[df.duplicated(subset=['dialogue'], keep=False)]
    Out[202]:
       dialogue  episode
    0     music        1
    6      wind        2
    7     music        1
    9     music        1
    10     wind        3
    

    如果要对结果进行排序:

    In [203]: df[df.duplicated(subset=['dialogue'], keep=False)].sort_values('dialogue')
    Out[203]:
       dialogue  episode
    0     music        1
    7     music        1
    9     music        1
    6      wind        2
    10     wind        3
    

    【讨论】:

    • 我有一个更广泛的担忧,如果我需要按照单词出现超过 5(或 7、8 或 9)次的条件进行过滤,那么应该改变什么跨度>
    【解决方案3】:

    我会使用value_counts

    vc = df.dialogue.value_counts() >= 2
    vc = vc[vc]
    df[df.dialogue.isin(vc.index)]
    


    时间

    请记住,这完全是多余的。不过,我正在磨练我的计时技巧。

    代码

    from timeit import timeit
    
    def pirsquared(df):
        vc = df.dialogue.value_counts() > 1
        vc = vc[vc]
        return df[df.dialogue.isin(vc.index)]
    
    def maxu(df):
        return df[df.groupby('dialogue')['episode'].transform('size') > 1]
    
    def andyhayden(df):
        return df.groupby("dialogue").filter(lambda x: len(x) > 1)
    
    rows = ['pirsquared', 'maxu', 'andyhayden']
    cols = ['OP_Given', '10000_3_letters']
    
    summary = pd.DataFrame([], rows, cols)
    iterations = 10
    
    df = pd.DataFrame({'dialogue': {0: 'music', 1: 'corrections', 2: 'somnath', 3: 'yadav', 4: 'join', 5: 'instagram', 6: 'wind', 7: 'music', 8: 'whimpering', 9: 'music', 10: 'wind'}, 'episode': {0: 1, 1: 1, 2: 1, 3: 5, 4: 2, 5: 1, 6: 2, 7: 1, 8: 2, 9: 1, 10: 3}})
    
    summary.loc['pirsquared', 'OP_Given'] = timeit(lambda: pirsquared(df), number=iterations)
    summary.loc['maxu', 'OP_Given'] = timeit(lambda: maxu(df), number=iterations)
    summary.loc['andyhayden', 'OP_Given'] = timeit(lambda: andyhayden(df), number=iterations)
    
    
    df = pd.DataFrame(
        pd.DataFrame(np.random.choice(list(lowercase), (10000, 3))).sum(1),
        columns=['dialogue'])
    df['episode'] = 1
    
    summary.loc['pirsquared', '10000_3_letters'] = timeit(lambda: pirsquared(df), number=iterations)
    summary.loc['maxu', '10000_3_letters'] = timeit(lambda: maxu(df), number=iterations)
    summary.loc['andyhayden', '10000_3_letters'] = timeit(lambda: andyhayden(df), number=iterations)
    
    
    summary
    

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2017-06-16
      • 1970-01-01
      • 2019-02-06
      • 1970-01-01
      • 2021-08-26
      • 2013-07-30
      • 2017-01-20
      • 2018-07-22
      相关资源
      最近更新 更多