我有两个Pandas DataFrames / Series,每个都包含一行。
df1 = pd.DataFrame([1, 2, 3, 4])
df2 = pd.DataFrame(['one', 'two', 'three', 'four'])
我现在想将所有可能的组合放入n * n矩阵/ DataFrame中,所有叉积的值都是自定义函数的输出。
def my_function(x, y):
return f"{x}:{y}"
因此,这将导致:
df = pd.DataFrame([['1:one', '2:one', '3:one', '4:one'],
['1:two', '2:two', '3:two', '4:two'],
['1:three', '2:three', '3:three', '4:three'],
['1:four', '2:four', '3:four', '4:four']])
0 1 2 3
0 1:one 2:one 3:one 4:one
1 1:two 2:two 3:two 4:two
2 1:three 2:three 3:three 4:three
3 1:four 2:four 3:four 4:four
虽然我可以通过itertools.product
构建自己的矩阵,但对于大型数据集而言,这似乎是一种非常低效的方法,我想知道是否还有一种更Python化的方法。预先谢谢你。
答案 0 :(得分:9)
让我们尝试np.add.outer
df = pd.DataFrame(np.add.outer(df1[0].astype(str).values,':'+df2[0].values).T)
Out[258]:
0 1 2 3
0 1:one 2:one 3:one 4:one
1 1:two 2:two 3:two 4:two
2 1:three 2:three 3:three 4:three
3 1:four 2:four 3:four 4:four
答案 1 :(得分:8)
您还可以将pd.DataFrame构造函数与apply
一起使用:
pd.DataFrame(index=df2.squeeze(), columns=df1.squeeze()).apply(lambda x: x.name.astype(str)+':'+x.index)
输出:
1 2 3 4
one 1:one 2:one 3:one 4:one
two 1:two 2:two 3:two 4:two
three 1:three 2:three 3:three 4:three
four 1:four 2:four 3:four 4:four
说明:
首先,使用pd.DataFrame构造函数,首先使用从df2和df1定义的索引和列来构建和清空数据框。使用pd.DataFrame.squeeze
,我们将那些单列数据帧转换为pd.Series。
接下来,使用pd.DataFrame.apply
,我们可以应用lambda函数,该函数将列名中的字符串添加冒号,并为数据帧的每一列添加数据帧索引。
这将创建一个具有索引和所需值的新数据框。
答案 2 :(得分:5)
使用np.tile
的另一种方法:
pd.DataFrame(np.tile(df1[0][:,None],df2.shape[0])).astype(str).add(":"+df2[0]).T
或类似但不转载@ Ch3ster礼貌
pd.DataFrame(np.repeat(df1[0].astype(str)[None,:],df2.shape[0],axis=0)).add(':'+df2[0])
0 1 2 3
0 1:one 2:one 3:one 4:one
1 1:two 2:two 3:two 4:two
2 1:three 2:three 3:three 4:three
3 1:four 2:four 3:four 4:four
编辑
要与函数一起使用,还可以使用交叉联接:
def my_function(x, y):
return f"{x}:{y}"
u = df1.assign(k=1).merge(df2.assign(k=1),on='k').drop('k',1).to_numpy()
arr = (np.array([*map(lambda x: my_function(*x),u)])
.reshape((df1.shape[0],df2.shape[0]),order='F'))
print(arr,"\n---------------------------------------------------\n",pd.DataFrame(arr))
[['1:one' '2:one' '3:one' '4:one']
['1:two' '2:two' '3:two' '4:two']
['1:three' '2:three' '3:three' '4:three']
['1:four' '2:four' '3:four' '4:four']]
---------------------------------------------------
0 1 2 3
0 1:one 2:one 3:one 4:one
1 1:two 2:two 3:two 4:two
2 1:three 2:three 3:three 4:three
3 1:four 2:four 3:four 4:four
答案 3 :(得分:4)
您可以添加它们,但是使用numpy.ndarray.ravel
pd.DataFrame(df1.astype(str).to_numpy().ravel() + ':' + df2.to_numpy())
0 1 2 3
0 1:one 2:one 3:one 4:one
1 1:two 2:two 3:two 4:two
2 1:three 2:three 3:three 4:three
3 1:four 2:four 3:four 4:four
答案 4 :(得分:2)
仅出于完整性考虑,以上答案仅适用于简单的用例。对于更复杂的自定义函数,这可能是最简单的(尽管有点难看)选项:
df = []
for i in df1.iterrows():
row = []
for j in df2.iterrows():
row.append(my_function(i[1][0], j[1][0]))
df.append(row)
pd.DataFrame(df)