【问题标题】:Join unique values into new data frame (python, pandas)将唯一值加入新数据框(python、pandas)
【发布时间】:2016-04-20 19:49:47
【问题描述】:

我有两个数据帧,我从中提取列的唯一值到 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
   . . .

有没有办法不使用循环?

【问题讨论】:

  • 列表理解可以接受吗?
  • 我需要它是DataFrame
  • @RoseAlejandra - 不,我在问是否可以接受列表理解来创建 DataFrame。你说没有'for循环',列表推导隐式使用,但不明确使用。
  • 我不介意隐式使用它们@AkshatMahajan
  • @RosaAlejandra,请注意 B.M. 的解决方案 - 它快得多

标签: python numpy pandas dataframe unique


【解决方案1】:

使用 numpy 工具:

pd.DataFrame({'col1':np.repeat(a,b.size),'col2':np.tile(b,a.size)})

【讨论】:

    【解决方案2】:

    更新:

    B. 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
    

    试试itertools.product:

    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
    

    【讨论】:

    • 由于itertools.product(a,b) 返回一个由元组组成的迭代器,我怀疑对[[x[0],x[1]] 的额外列表理解是不必要的。
    【解决方案3】:

    如果不使用至少一个 for 循环,您将无法完成此任务。您能做的最好的事情是隐藏 for 循环或利用隐式的yield 调用来创建内存高效的生成器。

    itertools为此任务导出高效函数,隐式使用yield返回生成器:

    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 productzip(*products) 只是将生成的元组列表解压缩为两个单独的元组,如 here 所示。

    【讨论】:

      【解决方案4】:

      您可以使用 pandas 合并来做到这一点,它会比 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']
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-28
        • 2014-01-25
        • 2023-03-22
        • 2013-10-05
        • 1970-01-01
        • 1970-01-01
        • 2018-03-04
        相关资源
        最近更新 更多