【问题标题】:Create dataframe from itertools product从 itertools 产品创建数据框
【发布时间】:2018-08-06 17:04:14
【问题描述】:

我有两个列表:

a = [1,2,3]
b = [4,5,6]

我想创建一个数据框,其中 (a,b) 的每个组合都会生成一个数据框 X,然后我选择 X 的最大值strong>,生成的输出行/列包含 ab 中的元素。

df=[]

for i, j in itertools.product(a, b):
    X = do_something(i,j)  ## this is a dataframe
    x_value = X.max()
    df.append(i,j,x_value)

df=pd.DataFrame(df, columns=['a', 'b', 'x_value'])

输出数据框的列应为 a,行应为 b,值应为 x_value

    1   2   3
4           
5           
6           

【问题讨论】:

  • 是的,没错——更新了
  • func 是否采用标量 ij?所以它必须在创建数据框之前或之后迭代地应用?
  • 不,函数非常复杂,但每次迭代 (i, j) 的最终结果是一个包含许多列的数据帧。然后我从列中选择一个值
  • 有两个问题,1) 为ab 的笛卡尔积生成x_value,以及2) 用ab 列排列Dataframe 中的值和行。您的代码 1) 很好,但创建了一个不同的数据框,一个有 3 列和 9 行。但数据都在那里。

标签: python pandas numpy dataframe itertools


【解决方案1】:

IIUC

df=pd.DataFrame(columns=a,index=b)
df.apply(lambda x : x.index+x.name)
Out[189]: 
   1  2  3
4  5  6  7
5  6  7  8
6  7  8  9

【讨论】:

    【解决方案2】:

    IIUC,您想知道如何从 (i, j, x) 值列表转到 DataFrame,其中 i 对应于列,j 对应于索引,x 对应于值:

    例如,如果您有:

    a = [1,2,3]
    b = [4,5,6]
    func = lambda i, j: i+j
    result = [(i, j, func(i,j)) for i, j in itertools.product(a, b)]
    print(result)
    #[(1, 4, 5),
    # (1, 5, 6),
    # (1, 6, 7),
    # (2, 4, 6),
    # (2, 5, 7),
    # (2, 6, 8),
    # (3, 4, 7),
    # (3, 5, 8),
    # (3, 6, 9)]
    

    将其转换为 DataFrame 的一种方法是使用 collections.defaultdict

    from collections import defaultdict
    
    d = defaultdict(list)
    
    for i, j, x in result:
        d[i].append(x)
    
    df = pd.DataFrame(d, index=b)
    print(df)
    #   1  2  3
    #4  5  6  7
    #5  6  7  8
    #6  7  8  9
    

    【讨论】:

    • 我正在简化 func(x),如果 x 比简单的加法更复杂怎么办?
    • 它必须是 itertools,因为每个 (i,j) 都会生成一个数据帧 (temp),我会在 temp 中选择一个特定的值
    • 每个 (i, j) 创建一个数据框 X,我挑出最大值
    • @user44840 我已根据您的最新更新修改了我的答案
    • 最适合创建 2d df
    【解决方案3】:

    您可以避免使用itertools.product,同时通过使用 numpy 和广播实现相同的功能:

    a = [1,2,3]
    b = [4,5,6]
    arr = np.array(a).reshape(-1, 1) + np.array(b).reshape(1, -1)
    df = pd.DataFrame(arr, columns=a, index=b)
    

    【讨论】:

      【解决方案4】:
      In [134]: a=[1,2,3]
      In [135]: b=[4,5,6]
      

      您的“指数”和值列表:

      In [140]: alist = []
      In [142]: for i,j in itertools.product(a,b):
           ...:     v = i*2 + j*.5
           ...:     alist.append([i,j,v])
           ...:     
      In [143]: alist
      Out[143]: 
      [[1, 4, 4.0],
       [1, 5, 4.5],
       [1, 6, 5.0],
       [2, 4, 6.0],
       [2, 5, 6.5],
       [2, 6, 7.0],
       [3, 4, 8.0],
       [3, 5, 8.5],
       [3, 6, 9.0]]
      

      一个 3 列的数据框:

      In [144]: df = pd.DataFrame(alist, columns=['a','b','value'])
      In [145]: df
      Out[145]: 
         a  b  value
      0  1  4    4.0
      1  1  5    4.5
      2  1  6    5.0
      3  2  4    6.0
      4  2  5    6.5
      5  2  6    7.0
      6  3  4    8.0
      7  3  5    8.5
      8  3  6    9.0
      

      使用相同数据制作“网格”数据框的一种方法:

      In [147]: pd.DataFrame(np.array(alist)[:,2].reshape(3,3), columns=a, index=b)
      Out[147]: 
           1    2    3
      4  4.0  4.5  5.0
      5  6.0  6.5  7.0
      6  8.0  8.5  9.0
      

      糟糕的是,错误地映射了行和列;让我们转置 3x3 数组:

      In [149]: pd.DataFrame(np.array(alist)[:,2].reshape(3,3).T, columns=a, index=b)
      Out[149]: 
           1    2    3
      4  4.0  6.0  8.0
      5  4.5  6.5  8.5
      6  5.0  7.0  9.0
      

      我很了解numpy;我对pandas 的经验有限。我敢肯定还有其他方法可以构建这样的框架。我的猜测是,如果你的价值函数足够复杂,迭代机制对整体运行时间的影响会很小。简单地评估每个单元格的功能将占用大部分时间。

      如果您的函数可以编写为采用数组而不是标量,则无需迭代即可轻松计算值。例如:

      In [171]: I,J = np.meshgrid(b,a,indexing='ij')
      In [172]: X = J*2 + I*.5
      In [173]: X
      Out[173]: 
      array([[4. , 6. , 8. ],
             [4.5, 6.5, 8.5],
             [5. , 7. , 9. ]])
      In [174]: I
      Out[174]: 
      array([[4, 4, 4],
             [5, 5, 5],
             [6, 6, 6]])
      In [175]: J
      Out[175]: 
      array([[1, 2, 3],
             [1, 2, 3],
             [1, 2, 3]])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-01
        相关资源
        最近更新 更多