繁体   English   中英

Python,Pandas; 按列中最常见的值对 Dataframe 行进行排序

[英]Python, Pandas; Sort Dataframe rows by most frequent values in a column

我有一个类似于此的 dataframe:

            A       B      C      D      E       F
0           4     422    470    101   4100  410000
1           4     422    470    101   4100  410000
2           4     422    470    101   4100  410000
3           4     422    470    101   4100  410000
4           4     422    470    101   4100  410000
...       ...     ...    ...    ...    ...     ...
33831       4     426    4ZD    4ZD   4989  498999
33832       4     426    4ZD    4ZD   4989  498999
33833       4     426    4ZD    4ZD   4989  498999
33834       4     426    4ZD    4ZD   4989  498999
33835       4     426    4ZD    4ZD   4989  498999

数据框应该显示从 A -> B -> C -> D -> E 的父子关系。E 中的每个子项在 D 中应该只有一个父项,D 到 C 等。但是,有E 中的孩子被误认为有不同的父母,我需要找到并注意。

# Remove duplicate rows to get the distinct relationships.
dfdrop = df.drop_duplicates()
print(dfdrop)


Output:

0           4     422    470    101   4100  410000
49          4     422    411    419   4102  410200
243         4     422    411    419   4103  410300
331         4     422    411    420   4108  410800
471         4     422    411    120  4120N  410900
...       ...     ...    ...    ...    ...     ...
33556       4      40    493    477   4970  497700
33727       4      40    493    477    4BE  497800
33752       4      40    457    4YR   4636  497900
33799       4      40    493    485   4982  498299
33822       4     426    4ZD    4ZD   4989  498999

[570 rows x 6 columns]

因为如果谱系中存在错误,E 列总是会重复,所以我尝试按 E 列值的频率对数据进行分组,并按大多数父子问题将它们排序到最少。 下面,计数表示需要审查的记录。 计数为 1 表示该记录没有父子问题。

dfgroups = dfdrop.groupby(['E']).size().reset_index().rename(columns={0:'count'})
print(dfgroups.sort_values(['count'], ascending=False).head(45))

Output:

          E  count
302  446099      4
53   418500      4
135  430130      3
459  474700      3
481  493099      3
496  496200      3
47   417500      3
448  472900      3
52   418400      3
435  470599      3
362  456099      3
60   419400      3
39   416099      2
483  493399      2
482  493199      2
170  433100      2
294  445300      2
234  439100      2
40   416100      2
361  455900      2
488  495399      2
313  448600      2
45   417300      2
411  463900      2
473  481600      2
61   419900      2
314  448700      2
489  495499      2
255  441100      2
327  450400      2
138  430300      2
253  440900      2
134  430099      2
431  470099      2
19   413400      2
136  430200      2
495  496199      2
493  495899      2
86   423400      2
338  452100      1
335  451800      1
349  453400      1
350  453500      1
334  451700      1
337  452099      1

现在,这告诉我 E 中的哪些值是重复的并且需要记录。 但是,我需要显示所有列并订购 dataframe 以便与未命中的记录匹配父子关系。 理想情况下,它看起来像这样:

0           4     422    470    101   4100  446099
49          4     422    411    419   4102  446099
243         4     422    411    419   4103  446099
331         4     422    411    420   4108  446099
471         4     422    411    120  4120N  418500
...       ...     ...    ...    ...    ...     ...
33556       4      40    493    477   4970  496199
33727       4      40    493    477    4BE  495899
33752       4      40    457    4YR   4636  495899
33799       4      40    493    485   4982  423400
33822       4     426    4ZD    4ZD   4989  423400

我将能够看到记录以及关系明显不同的地方。

尝试groupby_transform

假设这个 dataframe

>>> df
       A    B    C    D     E       F
0      4  422  470  101  4100  410000
1      4  422  470  101  4100  410000
2      4  422  470  101  4100  410000
3      4  422  470  101  4100  410000
4      4  422  470  101  4100  410000
33831  4  426  4ZD  4ZD  4989  498999
33832  4  426  4ZD  4ZD  4989  498999
33833  4  426  4ZD  4ZD  4989  498999
33834  4  426  4ZD  4ZD  4989  498999
33835  4  426  4ZD  4ZE  4989  498999
#                    ^------ Parent problem
mask = df.groupby('E')['D'].transform(lambda x: len(x.unique()) != 1)
bad_df = df.loc[mask, ['D', 'E']]
print(bad_df)

# Output:
         D     E
33831  4ZD  4989
33832  4ZD  4989
33833  4ZD  4989
33834  4ZD  4989
33835  4ZE  4989

您仍然可以减少 dataframe:

>>> bad_df.drop_duplicates()
         D     E
33831  4ZD  4989
33835  4ZE  4989

# OR

>>> bad_df.groupby(['D', 'E']).apply(lambda x: x.index.tolist()) \
          .rename('Index').reset_index()
     D     E                         Index
0  4ZD  4989  [33831, 33832, 33833, 33834]
1  4ZE  4989                       [33835]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM