【问题标题】:finding duplicates and adding ID as attribute pandas查找重复项并将 ID 添加为属性 pandas
【发布时间】:2021-12-07 00:05:33
【问题描述】:

我正在研究包含大量(大约 450 万个)对象的 geopanda,其中每个对象都有一个唯一的 ID 号('PARCEL_SPI')和另一个代码('PC_PLANNO')。

我想做的是编写一些代码,为每个对象找到具有相同 PLANNO 的所有其他对象,并将它们的 ID 号作为列表添加到新属性中,例如对象的“Same_code”。 df 称为 spin_copy。

这是我所拥有的快速示例:

PARCEL_SPI PC_PLANNO
23908 LP12345
90435 LP12345
329048 LP90803
6409 LP2399
34534 LP90803
092824 LP12345

以及我想要的:

PARCEL_SPI PC_PLANNO Same_code
23908 LP12345 [90435, 092824]
90435 LP12345 [23908,092824]
329048 LP90803 34534
6409 LP2399 None
34534 LP90803 329048
092824 LP12345 [23908, 90435]

我不太确定如何执行此操作,但这是我使用 groupby 的尝试:

spine_copy.groupby('PC_PLANNO')['PARCEL_SPI'].apply(list)

但是,这不会将列表添加为每个对象的新属性,我不确定如何执行此操作。

提前致谢!

【问题讨论】:

  • 您可以添加一些示例数据和预期输出吗?
  • 好点,补充!
  • 如果添加新行 1111 LP12345 会输出什么?
  • 不幸的是需要一个新属性——这个项目的输出基本上是一个大型数据库,每个对象都有属性
  • 那么如何改变预期输出?你能补充问题吗?

标签: python pandas dataframe geopandas


【解决方案1】:

此处无需转换为列表 - 通过 Series.duplicated 过滤重复的行并使用 GroupBy.transform 并将反转掩码传递给 numpy.where

m = spine_copy['PC_PLANNO'].duplicated(keep=False)
s = spine_copy.groupby('PC_PLANNO')['PARCEL_SPI'].transform(lambda x: x.to_numpy()[::-1])
spine_copy['Same_code'] = np.where(m, s, None)
print (spine_copy)
   PARCEL_SPI PC_PLANNO Same_code
0       23908   LP12345     90435
1       90435   LP12345     23908
2      329048   LP90803     34534
3        6409    LP2399      None
4       34534   LP90803    329048

编辑:使用新数据:

m = spine_copy['PC_PLANNO'].duplicated(keep=False)

new = spine_copy.groupby('PC_PLANNO')['PARCEL_SPI'].apply(list).rename('Same_code')
vals = spine_copy.join(new, on='PC_PLANNO')[['PARCEL_SPI','Same_code']]
s = [[z for z in y if z != x] for x, y in vals.to_numpy()]

spine_copy['Same_code'] = np.where(m, s, None)
print (spine_copy)
   PARCEL_SPI PC_PLANNO       Same_code
0       23908   LP12345  [90435, 92824]
1       90435   LP12345  [23908, 92824]
2      329048   LP90803         [34534]
3        6409    LP2399            None
4       34534   LP90803        [329048]
5       92824   LP12345  [23908, 90435]

【讨论】:

  • @SeaBean - 谢谢,添加 .to_numpy() 用于转换为 numpy 数组
  • 看到您更喜欢使用.to_numpy() 而不是.values。有什么理由吗?只是好奇。
  • @SeaBean - 当然,因为this
  • 感谢指出原因。非常感谢:-)
  • @jezrael 非常感谢,很好的解决方案!
【解决方案2】:

也许你可以试试:

other = df.groupby('PC_PLANNO')['PARCEL_SPI'].apply(lambda x: x.tolist()).reset_index()
df = df.merge(other.rename(columns={'PARCEL_SPI':'Same_code'}), how='left', on=['PC_PLANNO'])
df['Same_code'] = df[['PARCEL_SPI', 'Same_code']].apply(lambda x: list(set(x['Same_code']) - set([x['PARCEL_SPI']])), axis=1)

输出:

   PARCEL_SPI PC_PLANNO Same_code
0       23908   LP12345   [90435]
1       90435   LP12345   [23908]
2      329048   LP90803   [34534]
3        6409    LP2399        []
4       34534   LP90803  [329048]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多