在熊猫中设置联盟

时间:2016-07-18 03:16:09

标签: python python-3.x numpy pandas vectorization

我在我的数据框中存储了两列。

我想使用快速矢量化操作在两列上执行set union

df['union'] = df.set1 | df.set2

但错误TypeError: unsupported operand type(s) for |: 'set' and 'bool'阻止我这样做,因为我在两列中都输入了np.nan

有没有一个很好的解决方案可以解决这个问题?

2 个答案:

答案 0 :(得分:5)

对于这些操作,纯Python可能更有效。

%timeit pd.Series([set1.union(set2) for set1, set2 in zip(df['A'], df['B'])])
10 loops, best of 3: 43.3 ms per loop

%timeit df.apply(lambda x: x.A.union(x.B), axis=1)
1 loop, best of 3: 2.6 s per loop

如果我们可以使用+,它可能需要一半的时间(继承可能不值得):

%timeit df['A'] - df['B']
10 loops, best of 3: 22.1 ms per loop

%timeit pd.Series([set1.difference(set2) for set1, set2 in zip(df['A'], df['B'])])
10 loops, best of 3: 35.7 ms per loop

计时的DataFrame:

import pandas as pd
import numpy as np
l1 = [set(np.random.choice(list('abcdefg'), np.random.randint(1, 5))) for _ in range(100000)]
l2 = [set(np.random.choice(list('abcdefg'), np.random.randint(1, 5))) for _ in range(100000)]

df = pd.DataFrame({'A': l1, 'B': l2})

答案 1 :(得分:4)

这是我能想到的最好的:

# method 1
df.apply(lambda x: x.set1.union(x.set2), axis=1)

# method 2
df.applymap(list).sum(1).apply(set)

哇!

我期望方法2更快。不是这样!

enter image description here

实施例

df = pd.DataFrame([[{1, 2, 3}, {3, 4, 5}] for _ in range(3)],
                  columns=list('AB'))
df

enter image description here

df.apply(lambda x: x.set1.union(x.set2), axis=1)

0    {1, 2, 3, 4, 5}
1    {1, 2, 3, 4, 5}
2    {1, 2, 3, 4, 5}