【问题标题】:Create hash value for each row of data with selected columns in dataframe in python pandas在python pandas的数据框中为每行数据创建哈希值
【发布时间】:2020-07-06 16:48:16
【问题描述】:

我已经在 R 中询问了 similar question 关于为每行数据创建哈希值的问题。我知道我可以使用 hashlib.md5(b'Hello World').hexdigest() 之类的东西来散列一个字符串,但是数据框中的一行呢?

更新01

我的代码如下:

for index, row in course_staff_df.iterrows():
        temp_df.loc[index,'hash'] = hashlib.md5(str(row[['cola','colb']].values)).hexdigest()

对我来说似乎不是很 Python,有更好的解决方案吗?

【问题讨论】:

    标签: python hash pandas


    【解决方案1】:

    或者简单地说:

    df.apply(lambda x: hash(tuple(x)), axis = 1)
    

    举个例子:

    import pandas as pd
    import numpy as np
    df = pd.DataFrame(np.random.rand(3,5))
    print df
    df.apply(lambda x: hash(tuple(x)), axis = 1)
    
         0         1         2         3         4
    0  0.728046  0.542013  0.672425  0.374253  0.718211
    1  0.875581  0.512513  0.826147  0.748880  0.835621
    2  0.451142  0.178005  0.002384  0.060760  0.098650
    
    0    5024405147753823273
    1    -798936807792898628
    2   -8745618293760919309
    

    【讨论】:

      【解决方案2】:

      现在可以在pandas.util.hash_pandas_object

      pandas.util.hash_pandas_object(df)
      

      【讨论】:

      • 这没有回答问题:“在 Python Pandas 的 DataFrame 中为每一行数据创建哈希值”——一行在语义上首先不是 Pandas 对象——文档说出你给的函数:“返回索引/系列/数据帧的数据哈希” - 这些都不是“行”
      • 是的,文档不是很好。
      【解决方案3】:

      在python pandas的dataframe中为每一行数据创建哈希值

      这些解决方案适用于 Python 进程的整个生命周期。

      如果顺序很重要,一种方法是将行(一个 Series 对象)强制转换为一个元组:

      >>> hash(tuple(df.irow(1)))
      -4901655572611365671
      

      这说明了元组散列的顺序问题:

      >>> hash((1,2,3))
      2528502973977326415
      >>> hash((3,2,1))
      5050909583595644743
      

      要对每一行执行此操作,附加为一列将如下所示:

      >>> df = df.drop('hash', 1) # lose the old hash
      >>> df['hash'] = pd.Series((hash(tuple(row)) for _, row in df.iterrows()))
      >>> df
                 y  x0                 hash
      0  11.624345  10 -7519341396217622291
      1  10.388244  11 -6224388738743104050
      2  11.471828  12 -4278475798199948732
      3  11.927031  13 -1086800262788974363
      4  14.865408  14  4065918964297112768
      5  12.698461  15  8870116070367064431
      6  17.744812  16 -2001582243795030948
      7  16.238793  17  4683560048732242225
      8  18.319039  18 -4288960467160144170
      9  18.750630  19  7149535252257157079
      
      [10 rows x 3 columns]
      

      如果顺序无关紧要,请使用 freezesets 的哈希而不是元组:

      >>> hash(frozenset((3,2,1)))
      -272375401224217160
      >>> hash(frozenset((1,2,3)))
      -272375401224217160
      

      避免对行中所有元素的哈希求和,因为这可能在密码学上不安全,并导致哈希超出原始范围。

      (您可以使用模数来限制范围,但这相当于滚动您自己的哈希函数,最佳做法是。)

      您可以制作永久的加密质量哈希,例如使用 sha256 以及使用 the hashlib module.

      PEP 452 中有一些关于加密哈希函数 API 的讨论。

      感谢用户 Jamie Marshal 和 Discrete Lizard 的 cmets。

      【讨论】:

        【解决方案4】:

        我从问题中提供的代码中得出了这种改编:

        new_df2 = df.copy()
        key_combination = ['col1', 'col2', 'col3', 'col4']
        new_df2.index = list(map(lambda x: hashlib.sha1('-'.join([col_value for col_value in x]).encode('utf-8')).hexdigest(), new_df2[key_combination].values))
        

        【讨论】:

          【解决方案5】:
          df.set_index(pd.util.hash_pandas_object(df), drop=False, inplace=True)
          

          【讨论】:

          • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助,质量更高,更有可能吸引投票。
          猜你喜欢
          • 2020-09-27
          • 2018-03-15
          • 1970-01-01
          • 1970-01-01
          • 2021-10-17
          • 2022-11-16
          • 2019-05-31
          • 2018-11-13
          • 2020-09-05
          相关资源
          最近更新 更多