【问题标题】:Add numpy array as column to Pandas data frame将 numpy 数组作为列添加到 Pandas 数据框
【发布时间】:2013-09-09 20:43:15
【问题描述】:

我有一个形状为 (X,Y) 的 Pandas 数据框对象,如下所示:

[[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]

还有一个形状为 (X,Z) 的 numpy 稀疏矩阵 (CSC),看起来像这样

[[0, 1, 0],
[0, 0, 1],
[1, 0, 0]]

如何将矩阵中的内容添加到新命名列中的数据框中,以使数据框最终如下所示:

[[1, 2, 3, [0, 1, 0]],
[4, 5, 6, [0, 0, 1]],
[7, 8, 9, [1, 0, 0]]]

请注意,数据框现在具有 (X, Y+1) 形状,矩阵中的行是数据框中的元素。

【问题讨论】:

  • 不鼓励这种嵌套。为什么需要这样做?
  • 我想保留合并后通过单个列名选择矩阵先前内容的可能性。
  • 你为什么不用两个DataFrames?

标签: python numpy pandas


【解决方案1】:

您可以使用以下方法从数据框中添加和检索 numpy 数组:

import numpy as np
import pandas as pd

df = pd.DataFrame({'b':range(10)}) # target dataframe
a = np.random.normal(size=(10,2)) # numpy array
df['a']=a.tolist() # save array
np.array(df['a'].tolist()) # retrieve array

这建立在上一个答案的基础上,因为稀疏部分让我感到困惑,这对于非稀疏 numpy 数组非常有效。

【讨论】:

    【解决方案2】:
    df = pd.DataFrame(np.arange(1,10).reshape(3,3))
    df['newcol'] = pd.Series(your_2d_numpy_array)
    

    【讨论】:

      【解决方案3】:

      这是另一个例子:

      import numpy as np
      import pandas as pd
      
      """ This just creates a list of touples, and each element of the touple is an array"""
      a = [ (np.random.randint(1,10,10), np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
      range(0,10) ]
      
      """ Panda DataFrame will allocate each of the arrays , contained as a touple 
      element , as column"""
      df = pd.DataFrame(data =a,columns=['random_num','sequential_num'])
      

      秘诀一般是以 a = [ (array_11, array_12,...,array_1n),...,(array_m1,array_m2,...,array_mn) ] 的形式分配数据,panda DataFrame 将对 n 列数组中的数据进行排序。当然,可以使用数组的数组来代替 touples,在这种情况下,形式将是: a = [ [array_11, array_12,...,array_1n],...,[array_m1,array_m2,...,array_mn] ]

      如果您从上面的代码中打印(df),这是输出:

                             random_num                  sequential_num
      0  [7, 9, 2, 2, 5, 3, 5, 3, 1, 4]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      1  [8, 7, 9, 8, 1, 2, 2, 6, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      2  [3, 4, 1, 2, 2, 1, 4, 2, 6, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      3  [3, 1, 1, 1, 6, 2, 8, 6, 7, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      4  [4, 2, 8, 5, 4, 1, 2, 2, 3, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      5  [3, 2, 7, 4, 1, 5, 1, 4, 6, 3]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      6  [5, 7, 3, 9, 7, 8, 4, 1, 3, 1]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      7  [7, 4, 7, 6, 2, 6, 3, 2, 5, 6]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      8  [3, 1, 6, 3, 2, 1, 5, 2, 2, 9]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      9  [7, 2, 3, 9, 5, 5, 8, 6, 9, 8]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      

      上述示例的其他变体:

      b = [ (i,"text",[14, 5,], np.array([0,1,2,3,4,5,6,7,8,9]))  for i in 
      range(0,10) ]
      df = pd.DataFrame(data=b,columns=['Number','Text','2Elemnt_array','10Element_array'])
      

      df 的输出:

         Number  Text 2Elemnt_array                 10Element_array
      0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
      

      如果要添加其他列的数组,那么:

      df['3Element_array']=[([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3]),([1,2,3])]
      

      df 的最终输出将是:

         Number  Text 2Elemnt_array                 10Element_array 3Element_array
      0       0  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      1       1  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      2       2  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      3       3  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      4       4  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      5       5  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      6       6  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      7       7  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      8       8  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      9       9  text       [14, 5]  [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]      [1, 2, 3]
      

      【讨论】:

        【解决方案4】:

        考虑使用更高维度的数据结构(Panel),而不是在列中存储数组:

        In [11]: p = pd.Panel({'df': df, 'csc': csc})
        
        In [12]: p.df
        Out[12]: 
           0  1  2
        0  1  2  3
        1  4  5  6
        2  7  8  9
        
        In [13]: p.csc
        Out[13]: 
           0  1  2
        0  0  1  0
        1  0  0  1
        2  1  0  0
        

        看看横截面等等等等。

        In [14]: p.xs(0)
        Out[14]: 
           csc  df
        0    0   1
        1    1   2
        2    0   3
        

        See the docs for more on Panels.

        【讨论】:

        • 面板现已弃用
        • 是的,现在通常推荐使用 MultiIndex。创建例如通过pd.concat([df, csc], axis=1, keys=["df", "csc"]).
        • A = np.eye(3); df = pd.concat( [A,A], axis=1 ) -> TypeError: cannot concatenate a non-NDFrame object in 20.2 ? (“pandas-deprecated-now-use-this”的 wiki 会很好。)
        • @denis 试试A = pd.DataFrame(np.eye(3)); df = pd.concat( [A,A], axis=1, keys=["A", "B"] )
        • 谢谢,df.columns MultiIndex(levels=[[u'A', u'B'], [0, 1, 2]](拍了拍额头)
        【解决方案5】:
        import numpy as np
        import pandas as pd
        import scipy.sparse as sparse
        
        df = pd.DataFrame(np.arange(1,10).reshape(3,3))
        arr = sparse.coo_matrix(([1,1,1], ([0,1,2], [1,2,0])), shape=(3,3))
        df['newcol'] = arr.toarray().tolist()
        print(df)
        

        产量

           0  1  2     newcol
        0  1  2  3  [0, 1, 0]
        1  4  5  6  [0, 0, 1]
        2  7  8  9  [1, 0, 0]
        

        【讨论】:

        • 我想我们不能真正为坚持做这种事情的用户提供防弹鞋:/
        • interesting things you can do with a column of lists,所以我不想假设这一定是个坏主意。虽然我同意很有可能。
        • 这是pandas 灵活性的一个很好的例子。在 this 问题的情况下,数据已经是具有相同形状行的同质数字类型,而在该示例中,它们是不同长度的 lists。我同意你可以做一些有趣的事情。但是,当您已经有了一个矩阵时,为什么要把它变成一个列表列表呢?
        • 这里的“有趣的东西”......使它不再成为一列列表(所以它很有用)!
        • 当有创造力的人被允许做别人认为愚蠢的事情时,世界会变得更美好。 :)
        猜你喜欢
        • 2019-11-07
        • 1970-01-01
        • 1970-01-01
        • 2019-07-04
        • 1970-01-01
        • 2020-06-20
        • 1970-01-01
        • 2021-12-06
        相关资源
        最近更新 更多