Python 将存储为字符串的哈希ID列表转换为具有唯一值的列

Python 将存储为字符串的哈希ID列表转换为具有唯一值的列,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个数据帧,其中在一列中,我有一个哈希值列表,存储为字符串: '[d85235f50b3c019ad7c6291e3ca58093,03e0fb034f2cb3264234b9eae09b4287]' just to be clear. 数据帧看起来像 1 0 [8a88e629c368001c18619c7cd66d3e96, 4b0709dd990a0904bbe6afec636c4213, c00a98ceb6fc7006d572486787e551cc, 0e72ae6851c

我有一个数据帧,其中在一列中,我有一个哈希值列表,存储为字符串:

'[d85235f50b3c019ad7c6291e3ca58093,03e0fb034f2cb3264234b9eae09b4287]' just to be clear.
数据帧看起来像

  1
0 [8a88e629c368001c18619c7cd66d3e96, 4b0709dd990a0904bbe6afec636c4213, c00a98ceb6fc7006d572486787e551cc, 0e72ae6851c40799ec14a41496d64406, 76475992f4207ee2b209a4867b42c372]
1 [3277ded8d1f105c84ad5e093f6e7795d]
2 [d85235f50b3c019ad7c6291e3ca58093, 03e0fb034f2cb3264234b9eae09b4287]
我想创建此列中存在的唯一哈希id的列表

什么是有效的方法?
谢谢你

IIUC,你想把你的数据展平。使用
yaml.load
将其转换为列表列

import yaml

df = df.applymap(yaml.load)
print(df)
                                            1
0  [8a88e629c368001c18619c7cd66d3e96, 4b0709dd990...
1                 [3277ded8d1f105c84ad5e093f6e7795d]
2  [d85235f50b3c019ad7c6291e3ca58093, 03e0fb034f2...
最简单的方法是从旧数据框的值构造一个新的数据框

out = pd.DataFrame(np.concatenate(df.iloc[:, 0].values.tolist()))
print(out)

                                  0
0  8a88e629c368001c18619c7cd66d3e96
1  4b0709dd990a0904bbe6afec636c4213
2  c00a98ceb6fc7006d572486787e551cc
3  0e72ae6851c40799ec14a41496d64406
4  76475992f4207ee2b209a4867b42c372
5  3277ded8d1f105c84ad5e093f6e7795d
6  d85235f50b3c019ad7c6291e3ca58093
7  03e0fb034f2cb3264234b9eae09b4287
您需要使用first和for flatenning
链条

print (df.columns.tolist())
['col']

#convert strings to lists per rows
#change by your column name if necessary    
s = df['col'].str.strip('[]').str.split(', ')
print (s)
0    [8a88e629c368001c18619c7cd66d3e96, 4b0709dd990...
1                   [3277ded8d1f105c84ad5e093f6e7795d]
2    [d85235f50b3c019ad7c6291e3ca58093, 03e0fb034f2...
Name: col, dtype: object

#check first value
print (type(s.iat[0]))
<class 'list'>

#get unique values - for unique values use set
from  itertools import chain
L = list(set(chain.from_iterable(s)))

['76475992f4207ee2b209a4867b42c372', '3277ded8d1f105c84ad5e093f6e7795d',
 'd85235f50b3c019ad7c6291e3ca58093', '4b0709dd990a0904bbe6afec636c4213', 
 'c00a98ceb6fc7006d572486787e551cc', '03e0fb034f2cb3264234b9eae09b4287', 
 '8a88e629c368001c18619c7cd66d3e96', '0e72ae6851c40799ec14a41496d64406']

选项1
有关最快选项,请参见下面的计时

您可以将解析和展平嵌入到一个理解中

[y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')]

['8a88e629c368001c18619c7cd66d3e96',
 '4b0709dd990a0904bbe6afec636c4213',
 'c00a98ceb6fc7006d572486787e551cc',
 '0e72ae6851c40799ec14a41496d64406',
 '76475992f4207ee2b209a4867b42c372',
 '3277ded8d1f105c84ad5e093f6e7795d',
 'd85235f50b3c019ad7c6291e3ca58093',
 '03e0fb034f2cb3264234b9eae09b4287']
从那里,您可以使用
list(set())
pd.unique
,或
np.unique

pd.unique([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')])

array(['8a88e629c368001c18619c7cd66d3e96',
       '4b0709dd990a0904bbe6afec636c4213',
       'c00a98ceb6fc7006d572486787e551cc',
       '0e72ae6851c40799ec14a41496d64406',
       '76475992f4207ee2b209a4867b42c372',
       '3277ded8d1f105c84ad5e093f6e7795d',
       'd85235f50b3c019ad7c6291e3ca58093',
       '03e0fb034f2cb3264234b9eae09b4287'], dtype=object)

选项2
为简洁起见,请使用
pd.Series.extractall

list(set(df['1'].str.extractall('(\w+)')[0]))

['8a88e629c368001c18619c7cd66d3e96',
 '4b0709dd990a0904bbe6afec636c4213',
 'c00a98ceb6fc7006d572486787e551cc',
 '0e72ae6851c40799ec14a41496d64406',
 '76475992f4207ee2b209a4867b42c372',
 '3277ded8d1f105c84ad5e093f6e7795d',
 'd85235f50b3c019ad7c6291e3ca58093',
 '03e0fb034f2cb3264234b9eae09b4287']

@jezrael的
列表(set())
以我的理解是最快的

解析定时
我保留了相同的
列表(set())
,用于比较解析和展平

%timeit list(set(np.concatenate(df['1'].apply(yaml.load).values).tolist()))
%timeit list(set([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')]))
%timeit list(set(chain.from_iterable(df['1'].str.strip('[]').str.split(', '))))
%timeit list(set(df['1'].str.extractall('(\w+)')[0]))

1.01 ms ± 45 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.42 µs ± 219 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
279 µs ± 8.87 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
941 µs ± 10.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
这需要我的理解,并使用各种方法来比较这些速度

%timeit pd.unique([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')])
%timeit np.unique([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')])
%timeit list(set([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')]))

57.8 µs ± 3.66 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
17.5 µs ± 552 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
6.18 µs ± 184 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

什么意思?你想把柱子展平吗?是否要删除重复项?你能说清楚吗?看看我关于如何将字符串列转换为列表列的答案……如果你指的是另一个问题,那么我不这么认为。因为,如果你只想说“不要使用数据帧,使用一个系列”,但保持答案的其余部分不变,那么这也可以作为对我答案的评论添加。我会改进的。因为除此之外,它们都是一样的。但这取决于您。您是否也要添加
yaml.load
?谢谢:)一如既往,为了简单起见,您必须付出代价。那么
列表(set(chain.from_iterable([x.strip('[]')。在df['col']]中为x拆分(',')。values.tolist())
?我不知道什么是最快的;(df的大小是多少?是否有重复项?因为OP数据是唯一的:(简单的计时,没有调整大小。当我根据上一个建议运行
timeit
时出现奇怪的错误。我将显示一些内容。添加了您的方法。)。
%timeit pd.unique([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')])
%timeit np.unique([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')])
%timeit list(set([y for x in df['1'].values.tolist() for y in x.strip('[]').split(', ')]))

57.8 µs ± 3.66 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
17.5 µs ± 552 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
6.18 µs ± 184 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)