【问题标题】:Pandas - Giving all rows (particularly) duplicate rows a unique identifierPandas - 为所有行(特别是)重复行提供唯一标识符
【发布时间】:2019-02-06 05:05:02
【问题描述】:

假设我有一个 5 列的 DF,我想为每一行创建一个唯一的“键”。

   a  b  c  d  e
1  1  2  3  4  5
2  1  2  3  4  6
3  1  2  3  4  7 
4  1  2  2  5  6
5  2  3  4  5  6
6  2  3  4  5  6
7  3  4  5  6  7

我想创建一个“键”列,如下所示:

   a  b  c  d  e  key
1  1  2  3  4  5  12345
2  1  2  3  4  6  12346
3  1  2  3  4  7  12347
4  1  2  2  5  6  12256
5  2  3  4  5  6  23456
6  2  3  4  5  6  23456
7  3  4  5  6  7  34567

现在的问题当然是第 5 行和第 6 行是重复的。

我希望能够像这样创建唯一键:

   a  b  c  d  e  key
1  1  2  3  4  5  12345_1
2  1  2  3  4  6  12346_1
3  1  2  3  4  7  12347_1
4  1  2  2  5  6  12256_1
5  2  3  4  5  6  23456_1
6  2  3  4  5  6  23456_2
7  3  4  5  6  7  34567_1

不确定如何执行此操作或这是否是最佳方法 - 感谢任何帮助。

谢谢

编辑:列将主要是字符串,而不是数字。

【问题讨论】:

  • 你现在的1、2、3、4、5、6、7怎么了??

标签: python pandas key


【解决方案1】:

方法是散列到每一行的元组:

In [11]: df.apply(lambda x: hash(tuple(x)), axis=1)
Out[11]:
1   -2898633648302616629
2   -2898619338595901633
3   -2898621714079554433
4   -9151203046966584651
5    1657626630271466437
6    1657626630271466437
7    3771657657075408722
dtype: int64

In [12]: df['key'] = df.apply(lambda x: hash(tuple(x)), axis=1)

In [13]: df['key'].astype(str) + '_' + (df.groupby('key').cumcount() + 1).astype(str)
Out[13]:
1    -2898633648302616629_1
2    -2898619338595901633_1
3    -2898621714079554433_1
4    -9151203046966584651_1
5     1657626630271466437_1
6     1657626630271466437_2
7     3771657657075408722_1
dtype: object

注意:通常您不需要这样做(不清楚为什么要这样做!)。

【讨论】:

  • 这对我有用,一如既往地感谢安迪。这将在熊猫本身之外的匹配系统中使用,我需要唯一的标识符来匹配:)
  • @Andy Hayden - 很好的答案,我可以知道你为什么在这里使用hash 吗?
  • @MohamedThasinah 这是获取唯一标识符的好方法(不太可能发生哈希冲突)。哈!现在我看到你的回答我明白什么是 12345 :)
【解决方案2】:

试试这个。

df['key']=df.apply(lambda x:'-'.join(x.values.tolist()),axis=1)
m=~df['key'].duplicated()
s= (df.groupby(m.cumsum()).cumcount()+1).astype(str)
df['key']=df['key']+'_'+s
print (df)

O/P:

   a  b  c  d  e          key
0  1  2  3  4  5  1-2-3-4-5_0
1  1  2  3  4  6  1-2-3-4-6_0
2  1  2  3  4  7  1-2-3-4-7_0
3  1  2  2  5  6  1-2-2-5-6_0
4  2  3  4  5  6  2-3-4-5-6_0
5  2  3  4  5  6  2-3-4-5-6_1
6  3  4  5  6  7  3-4-5-6-7_0
7  1  2  3  4  5  1-2-3-4-5_1

另一种更简单的方法:

df['key']=df['key']+'_'+(df.groupby('key').cumcount()).astype(str)

解释:

  1. 首先使用 join 创建您的唯一 ID。
  2. 使用重复创建一个序列 s 并执行 cumsum,找到新值时重新启动。
  3. 最后连接 key 和你的序列 s。

【讨论】:

  • 只有''.join 行的问题是它不明确:[12, 3, 4, 5] 和 [1, 23, 4, 5] 转到同一个键
  • @AndyHayden - 是的,你是对的,现在得到hash 的严肃性,感谢您的信息:)
  • @AndyHayden - 我修好了,请看一下。
  • 有一点值得注意,这可能会变得很长(我们可以有几列任意长度的字符串),无论如何 +1
  • 哈,对于 1_2, 3, 4 和 1, 2_3, 4, 5 (如果某些列是字符串)仍然模棱两可;)
【解决方案3】:

也许你可以做一些链接下面的事情

import uuid
df['uuid'] = [uuid.uuid4() for __ in range(df.index.size)]

【讨论】:

    【解决方案4】:

    另一种方法是使用 np.random.choice(range(10000,99999), len(df), replace=False) 生成唯一的随机数,而不用替换 df 中的每一行:

    df = pd.DataFrame(columns = ['a', 'b', 'c', 'd', 'e'],
                      data = [[1,  2,  3,  4,  5],[1,  2,  3,  4,  6],[1,  2,  3,  4,  7],[1,  2,  2,  5,  6],[2,  3,  4,  5,  6],[2,  3,  4,  5,  6],[3,  4,  5,  6,  7]])
    
    df['key'] = np.random.choice(range(10000,99999), len(df), replace=False)
    
    df
    
        a   b   c   d   e   key
    0   1   2   3   4   5   10560
    1   1   2   3   4   6   79547
    2   1   2   3   4   7   24762
    3   1   2   2   5   6   95221
    4   2   3   4   5   6   79460
    5   2   3   4   5   6   62820
    6   3   4   5   6   7   82964
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-28
      • 2021-09-15
      • 2023-03-06
      • 2015-01-02
      • 2011-09-23
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      相关资源
      最近更新 更多