代码之家  ›  专栏  ›  技术社区  ›  user44840

从itertools产品创建dataframe

  •  0
  • user44840  · 技术社区  · 6 年前

    我有两个清单:

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

    我想创建一个数据框架,其中 (甲、乙) 生成数据帧 我找出最大值 ,结果输出行/列中的元素 .

    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'])
    

    输出数据帧的列应为 ,行为 ,值为 x_值 .

        1   2   3
    4           
    5           
    6           
    
    4 回复  |  直到 6 年前
        1
  •  1
  •   pault Tanjin    6 年前

    IIUC,你想知道如何从 (i, j, x) 值设置为数据帧,其中 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)]
    

    将其转换为数据帧的一种方法是 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
    
        2
  •  1
  •   BENY    6 年前

    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
    
        3
  •  0
  •   PMende    6 年前

    你可以避免使用 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
  •  0
  •   hpaulj    6 年前
    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
    

    使用相同数据生成“grid”数据帧的一种方法:

    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
    

    错误映射行和列的Oops;让我们转置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]])