【问题标题】:How to groupby in pandas dataframe by one column only if other column value is not same仅当其他列值不同时,如何在熊猫数据框中按一列分组
【发布时间】:2018-02-15 11:07:29
【问题描述】:

我有一个如下的数据框:

df
     ID  first    last
0   123    Joe  Thomas
1   456  James   Jonas
2   675  James   Jonas
3   457  James  Thomas

我想要如下输出:

{'Thomas': [123, 457], 'James':[675, 457]} 

对于'last' 相同但'first' 不同或'first' 相同但'last' 不同的所有行,获取这些行的ID。

我正在尝试这样做:

    for i in zip(df['ID'], df['first'], df['last']):
...     last.setdefault(i[2],[])
...     first.setdefault(i[1],[])
...     last[i[2]].append(i[0])
...     first[i[1]].append(i[0])

我得到的输出为:

>>> first
{'James': [456, 675, 457], 'Joe': [123]}
>>> last
{'Thomas': [123, 457], 'Jonas': [456, 675]}

但这仅按“第一个”或“最后一个”分组,并不会检查另一个是否相同。如何获得所需的输出?

更新:

将重复项删除为:

df = df.drop_duplicates(subset=['first', 'last'], take_last=False)

回答:

这样做了。不确定这是否正确。有什么建议吗?

new_d = pd.melt(df.sort_values('ID').drop_duplicates(['first','last']),'ID').groupby('value').ID.apply(list).to_dict()

low_d = {k:v for k, v in new_d.items() if len(v)!=1}

【问题讨论】:

  • 先删除重复的
  • 最接近我可以炮制的熊猫解决方案。甚至都不确定:df1 = pd.melt(df.groupby('first').apply(lambda x: x.drop_duplicates(['last'], keep='last')), 'ID', ['first', 'last'], 'denoms', 'names'); df1[df1.names.duplicated(keep=False)].groupby('names')['ID'].apply(list).to_dict().
  • 你用的是什么版本的python和pandas?您更新中的代码表明您使用的版本与@Abdou 使用的版本不同,这就是为什么您可能无法欣赏他的评论答案...如果您能够回答您的问题,请将其发布为答案回答你的问题并接受它。您对改进建议的请求可能会在 codereview.stackexchange.com 中更成功

标签: python pandas dictionary dataframe group-by


【解决方案1】:

基于@Abdou 在评论中提供的答案,我可以确认这适用于使用 Pandas 版本 0.20.1 的 Python 版本 2.7.13,以及使用 Pandas 版本 0.20.3 的 Python 版本 3.6.2:

from __future__ import division, print_function
import pandas as pd
import sys


def main():

    print("python version is: %s" % sys.version)
    print("pandas version: %s" % pd.__version__)

    df = pd.DataFrame(data={'first': ['Joe','James','James','James'],
                            'last': ['Thomas','Jonas','Jonas','Thomas'],
                            'ID': [123, 456, 675, 457]})

    grouped = df.groupby('first')\
                .apply(lambda x: x.drop_duplicates(['last'], keep='last'))

    melted = pd.melt(grouped, 'ID', ['first', 'last'], 'denoms', 'names')

    result = melted[melted.names.duplicated(keep=False)]\
                .groupby('names')['ID']

    print(result.apply(list).to_dict())

if __name__ == "__main__":
    main()

【讨论】:

    猜你喜欢
    • 2017-03-03
    • 2019-04-02
    • 2019-06-22
    • 2023-02-17
    • 2020-10-21
    • 2016-06-24
    • 1970-01-01
    • 2021-05-15
    • 1970-01-01
    相关资源
    最近更新 更多