我有一个pandas数据框如下:
如何将所有列表(在' val'列中)合并到一个唯一的列表(集合)中,例如[val1, val2, val33, val9, val6, val7]
?
我可以使用以下代码解决此问题。我想知道是否有更简单的方法从列中获取所有唯一值而不迭代数据帧行?
def_contributors=[]
for index, row in df.iterrows():
contri = ast.literal_eval(row['val'])
def_contributors.extend(contri)
def_contributors = list(set(def_contributors))
答案 0 :(得分:13)
将Series
导出为嵌套lists
,然后应用set
以展平列表的另一种解决方案:
df = pd.DataFrame({'id':['a','b', 'c'], 'val':[['val1','val2'],
['val33','val9','val6'],
['val2','val6','val7']]})
print (df)
id val
0 a [val1, val2]
1 b [val33, val9, val6]
2 c [val2, val6, val7]
print (type(df.val.ix[0]))
<class 'list'>
print (df.val.tolist())
[['val1', 'val2'], ['val33', 'val9', 'val6'], ['val2', 'val6', 'val7']]
print (list(set([a for b in df.val.tolist() for a in b])))
['val7', 'val1', 'val6', 'val33', 'val2', 'val9']
<强>计时强>:
df = pd.concat([df]*1000).reset_index(drop=True)
In [307]: %timeit (df['val'].apply(pd.Series).stack().unique()).tolist()
1 loop, best of 3: 410 ms per loop
In [355]: %timeit (pd.Series(sum(df.val.tolist(),[])).unique().tolist())
10 loops, best of 3: 31.9 ms per loop
In [308]: %timeit np.unique(np.hstack(df.val)).tolist()
100 loops, best of 3: 10.7 ms per loop
In [309]: %timeit (list(set([a for b in df.val.tolist() for a in b])))
1000 loops, best of 3: 558 µs per loop
如果类型不是list
但string
使用str.strip
和str.split
:
df = pd.DataFrame({'id':['a','b', 'c'], 'val':["[val1,val2]",
"[val33,val9,val6]",
"[val2,val6,val7]"]})
print (df)
id val
0 a [val1,val2]
1 b [val33,val9,val6]
2 c [val2,val6,val7]
print (type(df.val.ix[0]))
<class 'str'>
print (df.val.str.strip('[]').str.split(','))
0 [val1, val2]
1 [val33, val9, val6]
2 [val2, val6, val7]
Name: val, dtype: object
print (list(set([a for b in df.val.str.strip('[]').str.split(',') for a in b])))
['val7', 'val1', 'val6', 'val33', 'val2', 'val9']
答案 1 :(得分:5)
将该列转换为.apply(pd.Series)
的DataFrame。如果堆叠列,则可以在返回的Series上调用unique
方法。
df
Out[123]:
val
0 [v1, v2]
1 [v3, v2]
2 [v4, v3, v2]
df['val'].apply(pd.Series).stack().unique()
Out[124]: array(['v1', 'v2', 'v3', 'v4'], dtype=object)
答案 2 :(得分:1)
您可以使用str.concat
,然后进行一些string
操作,以获得所需的list
。
In [60]: import re
...: from collections import OrderedDict
In [62]: s = df['val'].str.cat()
In [63]: L = re.sub('[[]|[]]',' ', s).strip().replace(" ",',').split(',')
In [64]: list(OrderedDict.fromkeys(L))
Out[64]: ['val1', 'val2', 'val33', 'val9', 'val6', 'val7']
答案 3 :(得分:0)
一种方法是使用np.hstack
将这些元素提取到数组中,然后使用np.unique
为我们提供一系列这样的独特元素,如下所示 -
np.unique(np.hstack(df.val))
如果您想将列表作为输出,请附加.tolist()
-
np.unique(np.hstack(df.val)).tolist()