我有一个熊猫数据框:
| items
--------------
0 | [a]
1 | [a, b]
2 | [d, e, f,f]
3 | [d, f, e]
4 | [c, a, b]
我想计算列表中每个项目的出现频率,并构建一个如下表:
a| b| c| d| e| f
-------------------------
0| 1| 0| 0| 0| 0| 0
1| 1| 1| 0| 0| 0| 0
2| 0| 0| 0| 1| 1| 2
3| 0| 0| 0| 1| 1| 1
4| 1| 1| 1| 0| 0| 0
我看着pandas.explode,但我认为那不是我想要的。
我可以在下面做类似的事情。但是我觉得可能会有更有效的方法来做到这一点。我大约有350万行。
import pandas as pd
from collections import Counter,defaultdict
df = pd.DataFrame({'items':[['a'],['a','b'],
['d','e','f','f'],['d','f','e'],
['c','a','b']]})
alist = sum(sum(df.values.tolist(),[]),[]) # flatten the list
unique_list = sorted(set(alist)) # get unique value for column names
unique_list
b = defaultdict(list)
for row in sum(df.values.tolist(),[]):
counts = Counter(row)
for name in unique_list:
if name in counts.keys():
b[name].append(counts[name])
else:
b[name].append(0)
pd.DataFrame(b)
答案 0 :(得分:3)
由于子列表中有重复项,因此与pivot
相比,这更是一个get_dummies
问题,但是您首先需要扩展子列表。
您可以在此处使用Series.explode
,然后使用crosstab
。
ii = df['items'].explode()
pd.crosstab(ii.index, ii)
items a b c d e f
row_0
0 1 0 0 0 0 0
1 1 1 0 0 0 0
2 0 0 0 1 1 2
3 0 0 0 1 1 1
4 1 1 1 0 0 0
性能
df = pd.concat([df]*10_000, ignore_index=True)
In [91]: %timeit chris(df)
1.07 s ± 5.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [92]: %timeit user11871120(df)
15.8 s ± 124 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [93]: %timeit ricky_kim(df)
56.4 s ± 1.1 s per loop (mean ± std. dev. of 7 runs, 1 loop each)
答案 1 :(得分:2)
使用apply
和value_counts
的另一种方法:
<button class="collapsible" id="cfs">CFS Objects</button>
<div class="content">
<table>
<tr>
<td>
<button id="d_cfs">Download</button>
<button class="collapsible" id="cfs_policy">Policies</button>
<div class="content"><button id="d_cfs_policy">Download</button></div>
</td>
</tr>
</table>
</div>
</div>
输出:
df['items'].apply(pd.value_counts).fillna(0).astype(int)