将唯一值加入新数据框(python、pandas)
Join unique values into new data frame (python, pandas)
我有两个数据帧,从中我将列的唯一值提取到 a 和 b
a = df1.col1.unique()
b = df2.col2.unique()
现在a和b是这样的
['a','b','c','d'] #a
[1,2,3] #b
他们现在输入 numpy.ndarray
我想和他们一起拥有这样的 DataFrame
col1 col2
0 a 1
1 a 2
3 a 3
4 b 1
5 b 2
6 b 3
7 c 1
. . .
有没有不使用循环的方法?
更新:
乙。 M. 使用 numpy 的解决方案要快得多 - 我建议使用他的方法:
In [88]: %timeit pd.DataFrame({'col1':np.repeat(aa,bb.size),'col2':np.tile(bb,aa.size)})
10 loops, best of 3: 25.4 ms per loop
In [89]: %timeit pd.DataFrame(list(product(aa,bb)), columns=['col1', 'col2'])
1 loop, best of 3: 1.28 s per loop
In [90]: aa.size
Out[90]: 1000
In [91]: bb.size
Out[91]: 1000
In [56]: a
Out[56]:
array(['a', 'b', 'c', 'd'],
dtype='<U1')
In [57]: b
Out[57]: array([1, 2, 3])
In [63]: pd.DataFrame(list(product(a,b)), columns=['col1', 'col2'])
Out[63]:
col1 col2
0 a 1
1 a 2
2 a 3
3 b 1
4 b 2
5 b 3
6 c 1
7 c 2
8 c 3
9 d 1
10 d 2
11 d 3
如果不使用至少一个 for 循环,您将无法完成此任务。您可以做的最好的事情是 隐藏 for 循环或使用隐式 yield
调用来制作内存高效的生成器。
itertools
将隐式使用 yield
的此任务的高效函数导出到 return 生成器:
from itertools import product
products = product(['a','b','c','d'], [1,2,3])
col1_items, col2_items = zip(*products)
result = pandas.DataFrame({'col1':col1_items, 'col2': col2_items})
itertools.product
创建一个 Cartesian product of two iterables. The zip(*products)
simply unpacks the resulting list of tuples into two separate tuples, as seen here.
您可以使用 pandas merge 执行此操作,它会比 itertools 或循环更快:
df_a = pd.DataFrame({'a': a, 'key': 1})
df_b = pd.DataFrame({'b': b, 'key': 1})
result = pd.merge(df_a, df_b, how='outer')
结果:
a key b
0 a 1 1
1 a 1 2
2 a 1 3
3 b 1 1
4 b 1 2
5 b 1 3
6 c 1 1
7 c 1 2
8 c 1 3
9 d 1 1
10 d 1 2
11 d 1 3
然后如果需要你可以随时做
del result['key']
使用 numpy 工具:
pd.DataFrame({'col1':np.repeat(a,b.size),'col2':np.tile(b,a.size)})
我有两个数据帧,从中我将列的唯一值提取到 a 和 b
a = df1.col1.unique()
b = df2.col2.unique()
现在a和b是这样的
['a','b','c','d'] #a
[1,2,3] #b
他们现在输入 numpy.ndarray
我想和他们一起拥有这样的 DataFrame
col1 col2
0 a 1
1 a 2
3 a 3
4 b 1
5 b 2
6 b 3
7 c 1
. . .
有没有不使用循环的方法?
更新:
乙。 M. 使用 numpy 的解决方案要快得多 - 我建议使用他的方法:
In [88]: %timeit pd.DataFrame({'col1':np.repeat(aa,bb.size),'col2':np.tile(bb,aa.size)})
10 loops, best of 3: 25.4 ms per loop
In [89]: %timeit pd.DataFrame(list(product(aa,bb)), columns=['col1', 'col2'])
1 loop, best of 3: 1.28 s per loop
In [90]: aa.size
Out[90]: 1000
In [91]: bb.size
Out[91]: 1000
In [56]: a
Out[56]:
array(['a', 'b', 'c', 'd'],
dtype='<U1')
In [57]: b
Out[57]: array([1, 2, 3])
In [63]: pd.DataFrame(list(product(a,b)), columns=['col1', 'col2'])
Out[63]:
col1 col2
0 a 1
1 a 2
2 a 3
3 b 1
4 b 2
5 b 3
6 c 1
7 c 2
8 c 3
9 d 1
10 d 2
11 d 3
如果不使用至少一个 for 循环,您将无法完成此任务。您可以做的最好的事情是 隐藏 for 循环或使用隐式 yield
调用来制作内存高效的生成器。
itertools
将隐式使用 yield
的此任务的高效函数导出到 return 生成器:
from itertools import product
products = product(['a','b','c','d'], [1,2,3])
col1_items, col2_items = zip(*products)
result = pandas.DataFrame({'col1':col1_items, 'col2': col2_items})
itertools.product
创建一个 Cartesian product of two iterables. The zip(*products)
simply unpacks the resulting list of tuples into two separate tuples, as seen here.
您可以使用 pandas merge 执行此操作,它会比 itertools 或循环更快:
df_a = pd.DataFrame({'a': a, 'key': 1})
df_b = pd.DataFrame({'b': b, 'key': 1})
result = pd.merge(df_a, df_b, how='outer')
结果:
a key b
0 a 1 1
1 a 1 2
2 a 1 3
3 b 1 1
4 b 1 2
5 b 1 3
6 c 1 1
7 c 1 2
8 c 1 3
9 d 1 1
10 d 1 2
11 d 1 3
然后如果需要你可以随时做
del result['key']
使用 numpy 工具:
pd.DataFrame({'col1':np.repeat(a,b.size),'col2':np.tile(b,a.size)})