将numpy数组作为列添加到Pandas数据框


82

我有一个形状为(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),并且矩阵中的行是数据框中的元素。


2
不鼓励这种嵌套。为什么需要这样做?
菲利普·


我想保留合并后通过单个列名称选择矩阵的先前内容的可能性。
Mihai Damian

您为什么不只使用2 DataFrame
菲利普·乌云

Answers:


78
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]

6
我想我们不能为坚持这样做的用户提供防弹鞋:/
Phillip Cloud

6
您可以使用列表列来做一些有趣的事情,所以我宁愿不要认为这不一定是个坏主意。尽管我同意,但很有可能。
unutbu

1
这是pandas灵活性的一个很好的例子。在这个问题的情况下,数据已经是具有均等形状行的齐次数值类型,而在该示例中,它们list的长度不同。我同意您可以做一些有趣的事情。但是,当您已经有了矩阵时,为什么要将其转换为列表列表?
菲利普·

1
在“有趣的事情”有......使得它不是一个列表的列了(所以它是非常有用的)!
安迪·海登

51
当有创造力的人被允许做其他人都认为愚蠢的事情时,世界就会变得更美好。:)
unutbu 2013年

10

考虑使用更高维度的数据结构(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

有关面板的更多信息,请参见文档


11
小组现已弃用
Guhur

是的,通常现在建议使用MultiIndex。例如通过创建pd.concat([df, csc], axis=1, keys=["df", "csc"])
安迪·海登

A = np.eye(3); df = pd.concat( [A,A], axis=1 )-> TypeError:无法在20.2中连接非NDFrame对象?(“已弃用熊猫,现在使用此维基”的维基很好。)
denis

@denis tryA = pd.DataFrame(np.eye(3)); df = pd.concat( [A,A], axis=1, keys=["A", "B"] )
Andy Hayden

谢谢,df.columns MultiIndex(levels=[[u'A', u'B'], [0, 1, 2]](拍打额头)
denis

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))的形式分配数据,熊猫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]

0

对于普通的numpy数组,要添加和从数据框中检索,可以执行此操作。它建立在先前的答案上,这使我感到困惑,因为当我只有一个普通的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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.