【问题标题】:Groupby and compare/filter particular groups depending on other column in pandas dataframeGroupby 并根据熊猫数据框中的其他列比较/过滤特定组
【发布时间】:2019-08-27 14:42:39
【问题描述】:

我有一个像这样的df:

number   city        date
1        Denver_1     2019-01-14
1        Denver_1     2019-01-15
1        Denver_1     2019-01-16
1        Denver_2     2019-03-28
1        Denver_2     2019-03-29
2        Denver_1     2019-05-14
2        Denver_1     2019-05-15
2        Denver_1     2019-05-16
2        Denver_2     2019-01-28
2        Denver_2     2019-01-29
2        Seattle      2019-03-22
2        Seattle      2019-03-22
3        Denver_2     2019-05-28
3        Denver_2     2019-05-29
3        Seattle      2019-03-21
3        Seattle      2019-03-21

我想按 数字 分组并选择 Denver 与较高的日期 并离开 Seattle 的方式它们是因为它们不像 Denver 那样重复。 我想要的结果如下:

number   city        date
1        Denver_2     2019-03-28
1        Denver_2     2019-03-29
2        Denver_1     2019-05-14
2        Denver_1     2019-05-15
2        Denver_1     2019-05-16
2        Seattle      2019-03-22
2        Seattle      2019-03-22
3        Denver_2     2019-05-28
3        Denver_2     2019-05-29
3        Seattle      2019-03-21
3        Seattle      2019-03-21

我试过了:

df2 = df.groupby(['number']).apply(lambda x: x['city'].unique())

number
1       [Denver_1, Denver_2]
2       [Denver_1, Denver_2, Seattle]

它向我显示了每个数字的不同城市,但我不知道如何将最大日期过滤器添加到其中并将其应用于主 df。

我看到的使用 groupby().filter() 的其他示例将摆脱 Seattle 在我的情况下。

【问题讨论】:

    标签: python-3.x pandas filter group-by


    【解决方案1】:

    很遗憾,由于规则不同,我认为您需要分别处理丹佛和西雅图:

    加载您的示例数据:

    s = '''number   city        date
    1        Denver_1     2019-01-14
    1        Denver_1     2019-01-15
    1        Denver_1     2019-01-16
    1        Denver_2     2019-03-28
    1        Denver_2     2019-03-29
    2        Denver_1     2019-05-14
    2        Denver_1     2019-05-15
    2        Denver_1     2019-05-16
    2        Denver_2     2019-01-28
    2        Denver_2     2019-01-29
    2        Seattle      2019-03-22
    2        Seattle      2019-03-22
    3        Denver_2     2019-05-28
    3        Denver_2     2019-05-29
    3        Seattle      2019-03-21
    3        Seattle      2019-03-21'''
    
    
    df = pd.DataFrame.from_csv(io.StringIO(s), sep='\s+')
    df['date'] = pd.to_datetime(df['date'])
    df =df.reset_index()
    

    解决方案:

    selector = lambda x: x.loc[x['city'] == x.loc[x['date'].idxmax(), 'city']]
    denvers = df[df['city'].str.contains('Denver')].groupby('number', as_index=False).apply(selector)
    seattles = df[df['city'].str.contains('Seattle')]
    
    pd.concat([denvers.reset_index(level=0, drop=True), seattles], axis = 0).sort_index()
    

    输出:

        number      city       date
    3        1  Denver_2 2019-03-28
    4        1  Denver_2 2019-03-29
    5        2  Denver_1 2019-05-14
    6        2  Denver_1 2019-05-15
    7        2  Denver_1 2019-05-16
    10       2   Seattle 2019-03-22
    11       2   Seattle 2019-03-22
    12       3  Denver_2 2019-05-28
    13       3  Denver_2 2019-05-29
    14       3   Seattle 2019-03-21
    15       3   Seattle 2019-03-21
    

    【讨论】:

    • 非常感谢,ecortazar。这行得通。我只想为其他人提一下,如果您有更多 city 值,则可以执行 df[~df['city'].str.lower().str.contains('denver')]而不是 seattles = df[df['city'].str.contains('Seattle')]
    猜你喜欢
    • 2019-12-09
    • 2020-06-08
    • 1970-01-01
    • 2021-12-01
    • 2018-12-22
    • 2017-05-18
    • 2018-10-15
    • 1970-01-01
    • 2020-05-05
    相关资源
    最近更新 更多