python - 创建一个哈希确实在熊猫中定义组
问题描述
我有一个由几个元信息组成的数据框。如果所有特征都相同,则该行属于一个组。
假设这个数据框是一个简化的例子:
import pandas as pd
data = pd.DataFrame({"feature1": ["A", "A", "A", "B", "B", "B"]
, "feature2": [1,2,1,3,1,3]})
我现在想为每个不同的组合创建一个不同的标记,所以包括我的标记列,我希望这个数据框
expected_result = pd.DataFrame({"feature1": ["A", "A", "A", "B", "B", "B"]
, "feature2": [1,2,1,3,1,3]
, "hash": ["ab", "jk", "ab", "lu", "la", "lu"]})
feature1 feature2 hash
0 A 1 ab
1 A 2 jk
2 A 1 ab
3 B 3 lu
4 B 1 la
5 B 3 lu
def create_uniqueID(x, y, z): 如果 x 为 None: x = " " else: x = str(x) 如果 y 为 None: y = " " else: x = str(x) 如果 z 为 None: z = "_" 否则:x = str(x) 返回 x+y+z
自然地,我想到了散列这些数据,因此尝试了这个:
def create_uniqueID(x, y):
if x is None:
x = "_"
if y is None:
y = "_"
return hash(tuple([x,y]))
data["marker"] = data.apply(create_uniqueID(data.feature1, data.feature2))
但是比我得到的反馈,那个 Series 是可变的,因此不能被散列。所以我假设我必须按元素来做,但我不知道如何以简洁有效的方式做到这一点。
可以获取每列的所有值,对它们进行散列并重新附加它们,但我认为这不是一个好的解决方案。
解决方案
使用 lambda 函数分别处理每一行:
data["marker"] = data.apply(lambda x: create_uniqueID(x.feature1, x.feature2), axis=1)
print (data)
feature1 feature2 marker
0 A 1 -6565221176676644544
1 A 2 -6565221176675562019
2 A 1 -6565221176676644544
3 B 3 4352711037653751181
4 B 1 4352711037651586131
5 B 3 4352711037653751181
另一个想法是使用 lambda 函数,但在将None
s 替换为之前_
:
np.random.seed(123)
N = 10000
L = list('abcdef') + [None]
data = pd.DataFrame({'feature1': np.random.choice(L, N),
'feature2':np.random.randint(100, size=N)})
#print (data)
data["marker1"] = data.fillna('_').apply(lambda x: hash(tuple(x)), axis=1)
print (data)
feature1 feature2 marker1
0 None 73 -2622163292899442353
1 f 93 6883629009348118745
2 None 73 -2622163292899442353
3 c 95 8232223848018743176
4 e 95 -4199008080420766281
... ... ...
9995 e 42 -4199008080510615856
9996 b 65 -2981575294812687977
9997 c 95 8232223848018743176
9998 None 19 -2622163292940578303
9999 None 61 -2622163292990374453
[10000 rows x 3 columns]
10k 行的性能不同,它取决于 DataFrame 的长度:
np.random.seed(123)
def create_uniqueID(x, y):
if x is None:
x = "_"
if y is None:
y = "_"
return hash(tuple([x,y]))
N = 10000
L = list('abcdef') + [None]
data = pd.DataFrame({'feature1': np.random.choice(L, N),
'feature2':np.random.randint(100, size=N)})
#print (data)
data["marker0"] = data.apply(lambda x: create_uniqueID(x.feature1, x.feature2), axis=1)
data["marker1"] = data.fillna('_').apply(lambda x: hash(tuple(x)), axis=1)
data['hash1'] = [hash(''.join(str(y) for y in x[1].values)) for x in data.iterrows()]
data['hash2'] = data.apply(lambda x: hash(str(x.feature1)+str(x.feature2)), axis=1)
print (data)
In [183]: %timeit data.apply(lambda x: create_uniqueID(x.feature1, x.feature2), axis=1)
332 ms ± 25.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [184]: %timeit data.fillna('_').apply(lambda x: hash(tuple(x)), axis=1)
212 ms ± 17.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [185]: %timeit [hash(''.join(str(y) for y in x[1].values)) for x in data.iterrows()]
996 ms ± 113 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [186]: %timeit data.apply(lambda x: hash(str(x.feature1)+str(x.feature2)), axis=1)
326 ms ± 8.09 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
推荐阅读
- python-2.7 - 我如何在python中搜索字符串的一部分
- java - @Embeddable 是 Foo.class' PK 和 Bar.class' FK 到 Foo.class
- c++ - c++ raspberry pi 4 - 在没有输入/验证的情况下获取键盘键输入?
- kubernetes - 使本地 requirements.txt 文件可用于 microk8s stable/airflow
- python - html 页面中的输出不正确。烧瓶
- asp.net - .NET App 正在运行但未在浏览器中显示
- java - 模拟一个复杂的 api 调用
- java - JavaFX 在屏幕上的任何位置等待点击
- python - 从求和条件中获取熊猫索引值的矢量化方法
- html - 是否可以设置一个`