【问题标题】:Efficient product of columns in PandasPandas 中列的高效乘积
【发布时间】:2017-09-17 13:50:47
【问题描述】:

我想知道是否可以通过 Pandas 函数实现以下功能。给定两个 Pandas DataFrame,得到一个新的 DataFrame,其列是两个给定 DataFrame 中列的笛卡尔积。也就是说,在一个简单的例子中,如果我们有两个 DataFrame:

df1 = pd.DataFrame([[1,2], [1,2]], columns = ['a', 'b'])
df2 = pd.DataFrame([[3,4], [3,4]], columns = ['c', 'd'])

看起来像

df1                 df2
   a  b                c  d
0  1  2             0  3  4
1  1  2             1  3  4

我正在寻找一个无需循环即可提供以下功能的函数:

df
   a_c  a_d  b_c  b_d
0  3    4    6    8
1  3    4    6    8

【问题讨论】:

  • 笛卡尔积不会是别的东西,比如 (1,3) (1,4) (2,3) (2,4) \\ (1,3) (1,4 ) (2,3) (2,4) ?请参阅stackoverflow.com/a/35268188/4248972 以获得答案
  • 为了吸引 Numpy 专家,我将标签更改为 numpy...

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


【解决方案1】:

您可以将pd.concatadd_prefixmul df2df1 的系列一起使用。

In [806]: pd.concat([df2.mul(df1[c], axis=0).add_prefix(c+'_') for c in df1], axis=1)
Out[806]:
   a_c  a_d  b_c  b_d
0    3    4    6    8
1    3    4    6    8

【讨论】:

    【解决方案2】:

    这可能是一个选项:

    dfjoin = pd.concat((df2.mul(y, axis=0) for _, y in df1.iteritems()), axis=1, keys=df1)
    # This next line courtesy of MaxU's comment:
    dfjoin.columns = dfjoin.columns.map('_'.join)
    dfjoin
       a_c  a_d  b_c  b_d
    0    3    4    6    8
    1    3    4    6    8
    

    【讨论】:

    • 谢谢,是的,这可以正确获取列的内容。但是是否也可以获取一维索引中的列?
    • @splinter,试试这个r.columns = r.columns.swaplevel().map('_'.join),其中r 是生成的DF
    • @MaxU,没错!
    【解决方案3】:

    这是一个 NumPy 方法,使用 broadcasting 处理底层数组数据,重点关注性能效率 -

    out = (df2.values[:,None] * df1.values[:,:,None]).reshape(df1.shape[0],-1)
    cols = [i+'_'+j for i in df1.columns for j in df2.columns]
    df_out = pd.DataFrame(out, columns = cols)
    

    【讨论】:

    • 这太棒了!
    • @MaxU 感谢您添加 NumPy 标签!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 1970-01-01
    • 2018-04-12
    • 2021-10-04
    • 2016-07-09
    • 1970-01-01
    • 2016-04-14
    相关资源
    最近更新 更多