【问题标题】:How to extract data based on number of duplicate rows?如何根据重复行数提取数据?
【发布时间】:2020-04-23 17:24:03
【问题描述】:

我有一个包含多行的数据集。我想根据列的重复行数创建一个新数据集。对于第一个数据集,我想要一个没有重复行的数据集,这意味着只有具有一个值的行。对于第二个数据集,我想要两个重复的行和三个重复的行,但最多只有第二个。对于第三个数据集,我想要一个只有三个重复行的数据集。因此,作为一个例子,我编写了代码来描述这种情况。假设我有一个这样的数据框

x = {'column1': ['a','a','b','b','b','c','c','c','d'],
    'column2': [22000,25000,27000,350,0,3,5,4,312]
    }
df = pd.DataFrame(x, columns = ['column1', 'column2'])
print (df)

第一个数据集应该是这样的:

x = {'column1': ['d'],
    'column2': [312]
    }
df = pd.DataFrame(x, columns = ['column1', 'column2'])
print (df)

第二个数据集应该是这样的:

x = {'column1': ['a','a','b','b','c','c'],
    'column2': [22000,25000,27000,350,3,5]
    }
df = pd.DataFrame(x, columns = ['column1', 'column2'])
print (df)

第三个数据集应该如下所示:

x = {'column1': ['b','b','b','c','c','c'],
    'column2': [27000,350,0,3,5,4]
    }
df = pd.DataFrame(x, columns = ['column1', 'column2'])
print (df)

我怎么能不手动呢?

【问题讨论】:

    标签: python pandas numpy data-manipulation data-cleaning


    【解决方案1】:

    首先按计数创建计数器Series

    x = {'column1': ['a','a','b','b','b','c','c','c','d'],
        'column2': [22000,25000,27000,350,0,3,5,4,312]
        }
    df = pd.DataFrame(x, columns = ['column1', 'column2'])
    print (df)
    
    s = df.groupby('column1')['column1'].transform('size')
    #alternative
    #s = df['column1'].map(df['column1'].value_counts())
    print (s)
    0    2
    1    2
    2    3
    3    3
    4    3
    5    3
    6    3
    7    3
    8    1
    Name: column1, dtype: int64
    

    然后在列表推导中使用GroupBy.head 过滤器创建DataFrame:

    L = [df[s >= i].groupby(['column1',s]).head(i) if i > 1 else g for i, g in df.groupby(s)]
    print (L[0])
    print (L[1])
    print (L[2])
      column1  column2
    8       d      312
      column1  column2
    0       a    22000
    1       a    25000
    2       b    27000
    3       b      350
    5       c        3
    6       c        5
      column1  column2
    2       b    27000
    3       b      350
    4       b        0
    5       c        3
    6       c        5
    7       c        4
    

    EDIT1:因为解决方案更复杂,所以创建了自定义函数,并且对于具有3 值的行使用GroupBy.nth

    def func(x, g):
        if x == 1:
            return g
        else:
            df1 = df[s >= x].groupby(['column1',s]).head(x)
            if x == 3:
                return (df1.groupby(['column1',s], group_keys=False)
                           .nth([0, -1])
                           .reset_index(level=1, drop=True)
                           .reset_index())
    
            else:
                return df1
    
    L = [func(i, g) for i, g in df.groupby(s)]
    print (L[0])
    print (L[1])
    print (L[2])
      column1  column2
    8       d      312
      column1  column2
    0       a    22000
    1       a    25000
    2       b    27000
    3       b      350
    5       c        3
    6       c        5
      column1  column2
    0       b    27000
    1       b        0
    2       c        3
    3       c        4
    

    【讨论】:

    • 这些似乎是很好的解决方案,但我如何从这个解决方案中制作数据集?
    • 您可以将L[0] 用于第一个DataFrame,L[1] 用于第二个...类似于第二个解决方案d[1]d[2]。就像使用df1, df2...
    • 实际上,对于第二个数据集(L[1]),条件是两个重复行和三个重复行,但只能到第二个。我认为条件的第二部分缺失。当我在其他数据集上尝试此代码时,我仍然看到三个重复的行
    • WOW 完美运行,但我能再问你一件事,而第三个数据集的条件几乎没有变化。对于第三个数据集,我仍然想要具有三个重复行的行,但只是第一行和最后一行。我该怎么做?
    • @Godseph - 仅适用于 3 个 DataFrame 需要 {'column1': ['b', 'b', 'c', 'c'], 'column2': [27000, 0, 3, 4]} ?
    【解决方案2】:

    另一种解决方案是找到column1count 并找到与column1 具有相同计数的数据帧的子集

    df2 = df.groupby(['column1']).agg({'column2' : 'count'}).reset_index()
    for cnt in df2['column2'].sort_values().unique():
        print(df[df['column1'].isin(df2[df2['column2'] == cnt]['column1'])])
    

    它会给你输出

      column1  column2
    8       d      312
      column1  column2
    0       a    22000
    1       a    25000
      column1  column2
    2       b    27000
    3       b      350
    4       b        0
    5       c        3
    6       c        5
    7       c        4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-30
      • 2018-05-26
      • 1970-01-01
      • 2016-11-29
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2018-04-02
      相关资源
      最近更新 更多