【问题标题】:How to select row information in dataframe over ID如何在 ID 上选择数据框中的行信息
【发布时间】:2020-06-16 17:54:36
【问题描述】:

我是 python 新手。我有一个像这样的大数据框:

    ID  x   y
0   1   x1  y1
1   0   x2  y2
2   0   x3  y3
3   2   x4  y4
4   1   x5  y5
5   2   x6  y6

我想在 ID 1 和 2 之间取几个 (x;y),在这样的数据框中:

    coordinates
0   (x1,y1), (x2,y2), (x3,y3), (x4,y4)
1   (x5,y5), (x6,y6)

我已经尝试过使用 double 进行迭代,但计算时间太长了。我怎么才能得到这个东西?

【问题讨论】:

  • 这里的逻辑是什么?为什么您的输出中的0 包含来自ID 的102 的坐标?
  • 我想根据 ID 构建一些轨迹:1 是开始,2 是结束,0 在这两者之间

标签: python pandas dataframe iteration selection


【解决方案1】:

一个想法是按每个 1 起始值创建组并为元组聚合自定义 lambda 函数:

df['new'] = (df['ID'] == 1).cumsum()
print (df)
   ID   x   y  new
0   1  x1  y1    1
1   0  x2  y2    1
2   0  x3  y3    1
3   2  x4  y4    1
4   1  x5  y5    2
5   2  x6  y6    2

df1 = (df.groupby('new')['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]

没有新列的类似解决方案:

df1 = (df.groupby((df['ID'].rename('new') == 1).cumsum())['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]

编辑:

print (df)
   ID   x   y
0   1  x1  y1
1   0  x2  y2
2   0  x3  y3
3   2  x4  y4
4   0  x7  y7
4   0  x8  y8
4   1  x5  y5
5   2  x6  y6

g = df['ID'].eq(1).cumsum()
s = df['ID'].shift().eq(2).cumsum()

df = df[s.groupby(g).transform('min').eq(s)]
print (df)
   ID   x   y
0   1  x1  y1
1   0  x2  y2
2   0  x3  y3
3   2  x4  y4
4   1  x5  y5
5   2  x6  y6

df1 = (df.groupby((df['ID'].rename('new') == 1).cumsum())['x','y']
         .apply(lambda x: list(map(tuple, x.values.tolist())))
         .reset_index(name='coordinates'))
print (df1)
   new                               coordinates
0    1  [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
1    2                      [(x5, y5), (x6, y6)]

【讨论】:

  • 即使不存在结尾“2”值,解决方案也会创建组。例如,如果 ID=[1,0,1,2,1,2] 将创建三个组,而不是直接按照要求创建 2 个。只有当数据中有完整的边界(1,2)时才可以分组?
  • 非常感谢!如果 2 和 1 之间有一些 0 怎么办?如果有的话我更愿意问..
  • @jezrael 抱歉,我是新来的,我以为我们可以接受两个答案...这样,你能帮帮我吗?
  • @nicolax9777 - 当然,我帮你。
  • @jezrael 非常感谢!太棒了,运行只需 5 秒
【解决方案2】:

您可以在轴 1 上使用 apply 元组,并使用 cumsumeq(1) 使用 groupby 您的“组”并使用 list aggregation

(df[['x', 'y']].apply(tuple, axis=1)
 .groupby(df['ID'].eq(1).cumsum()).agg(list))

[出]

ID
1    [(x1, y1), (x2, y2), (x3, y3), (x4, y4)]
2                        [(x5, y5), (x6, y6)]
dtype: object

或者如果预期的输出是一个逗号分隔的坐标字符串,你可以applyjoin函数:

(df[['x', 'y']].apply(tuple, axis=1).astype(str)
 .groupby(df['ID'].eq(1).cumsum()).apply(', '.join))

[出]

ID
1    ('x1', 'y1'), ('x2', 'y2'), ('x3', 'y3'), ('x4', 'y4')
2                                ('x5', 'y5'), ('x6', 'y6')
dtype: object

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-18
    • 2016-03-24
    • 2016-07-08
    • 1970-01-01
    • 2019-02-11
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多