2017-08-25 141 views
0

我使用python熊猫在DataFrame中组织一些测量值。 列的一个是我想在2D矢量转换值,所以我们说,列包含这样的值:用熊猫中的一列向量替换一列值

col1 
25 
12 
14 
21 

我想有此列的值通过逐个改变(在for循环):

for value in values: 
    df.['col1'][value] = convert2Vector(df.['col1'][value]) 

以使得该柱col1变为:

col1 
[-1. 21.] 
[-1. -2.] 
[-15. 54.] 
[11. 2.] 

的值仅仅是示例并且函数convert2Vector() CON将角度转换为2D向量。

随着for -loop,我写这是行不通的。我得到的错误:

ValueError: setting an array element with a sequence. 

,我可以理解。

所以问题是:如何做到这一点?

回答

0

这个例外来自于您希望在存储int s的列(array)中插入listarray这一事实。并且Pandas和NumPy中的array不能有“粗糙的形状”,因此不能在一行中包含2个元素,而在其他所有其他元素中(除了可能使用掩码)。

为了使它工作,你需要存储“一般”对象。例如:

import pandas as pd 

df = pd.DataFrame({'col1' : [25, 12, 14, 21]}) 
df.col1[0] = [1, 2] 
# ValueError: setting an array element with a sequence. 

但这个工程:

>>> df.col1 = df.col1.astype(object) 
>>> df.col1[0] = [1, 2] 
>>> df 
    col1 
0 [1, 2] 
1  12 
2  14 
3  21 

注:我不建议这样做,由于object列是不是专门类型的列慢得多。但是因为你用for循环遍历Column,所以你不需要性能,所以你也可以使用object数组。


如果你想让它快是矢量化convert2vector功能和结果分配给两列,你应该做的事情:

import pandas as pd 
import numpy as np 

def convert2Vector(angle): 
    """I don't know what your function does so this is just something that 
    calculates the sin and cos of the input...""" 
    ret = np.zeros((angle.size, 2), dtype=float) 
    ret[:, 0] = np.sin(angle) 
    ret[:, 1] = np.cos(angle) 
    return ret 

>>> df = pd.DataFrame({'col1' : [25, 12, 14, 21]}) 
>>> df['col2'] = [0]*len(df) 
>>> df[['col1', 'col2']] = convert2Vector(df.col1) 
>>> df 
     col1  col2 
0 -0.132352 0.991203 
1 -0.536573 0.843854 
2 0.990607 0.136737 
3 0.836656 -0.547729 
+0

谢谢!然后为了使用矢量的元素作为实数,我需要再次转换它们吗? –

+0

@ BenJo你的意思是在第二种情况下还是第一种情况?在第二种情况下很容易:只需在需要第一项的'col1'和需要第二项的'col2'处使用。如果你在谈论第一种情况,你可以使用'np.array(df。col1)'将其转换为'rows x 2'数组:) – MSeifert

+0

2列解决方案的问题在于,我必须将数据集导入数据库中,并使用定义的列数,以便第一个解决方案更好。特别是如果我仍然可以作为实数访问向量的元素 –

1

你应该叫一次函数像df.applydf.transform它创建一个新的列,然后你分配回:

In [1022]: df.col1.apply(lambda x: [x, x // 2]) 
Out[1022]: 
0 [25, 12] 
1  [12, 6] 
2  [14, 7] 
3 [21, 10] 
Name: col1, dtype: object 

在你的情况下,你会这样做:

df['col1'] = df.col1.apply(convert2vector) 
+0

''应用''系列'就像'for'循环一样慢。在这种情况下,它更慢,因为它有一个间接层('lambda')。但仍然是一个很好的答案,只需要更多的澄清。 :) – MSeifert

+0

@ MSeifert这是我的愚蠢。拉姆达不需要! –

+0

这不是我的意思。 “系列”上的“应用”只是一个更好的隐藏反模式。但没有'lambda'会更好一些:D – MSeifert