如何遍历数据框中的列并同时更新两个新列?
How to iterate through a column in dataframe and update two new columns simultaneously?
我知道我可以向数据框添加一列并将其值更新为从函数返回的值,如下所示:
df=pd.DataFrame({'x':[1,2,3,4]})
def square(x):
return x*x
df['x_squared'] = [square(i) for i in df['x']]
但是,我遇到了实际函数返回两项的问题,我想将这两项放在两个不同的新列中。我在这里写了一个伪代码来更清楚地描述我的问题:
df=pd.DataFrame({'x':[1,2,3,4]})
def squareAndCube(x):
return x*x, x*x*x
#below is a pseudo-code
df['x_squared'], df['x_cubed'] = [squareAndCube(i) for i in df['x']]
上面的代码给我一条错误消息说 "too many values to unpack"。
那么,我应该如何解决这个问题?
你可以用矢量化的方式来做,像这样 -
df['x_squared'], df['x_cubed'] = df.x**2,df.x**3
或者像这样使用自定义函数 -
df['x_squared'], df['x_cubed'] = squareAndCube(df.x)
回到你的循环案例,在作业的右侧,你有:
In [101]: [squareAndCube(i) for i in df['x']]
Out[101]: [(1, 1), (4, 8), (9, 27), (16, 64)]
现在,在左侧,您有 df['x_squared'], df['x_cubed'] =
。因此,它期望所有行的平方数作为第一个输入分配。从上面显示的列表中,第一个元素不是那个,它实际上是第一行的正方形和立方体。因此,解决方法是 "transpose" 列出并指定为新列。因此,修复将是 -
In [102]: L = [squareAndCube(i) for i in df['x']]
In [103]: map(list, zip(*L)) # Transposed list
Out[103]: [[1, 4, 9, 16], [1, 8, 27, 64]]
In [104]: df['x_squared'], df['x_cubed'] = map(list, zip(*L))
为了 NumPy broadcasting
的爱!
df['x_squared'], df['x_cubed'] = (df.x.values[:,None]**[2,3]).T
这样使用 df.loc
怎么样:
df=pd.DataFrame({'x':[1,2,3,4]})
def square(x):
return x*x
df['x_squared'] = df['x_cubed'] = None
df.loc[:, ['x_squared', 'x_cubed']] = [squareAndCube(i) for i in df['x']]
给予
x x_squared x_cubed
0 1 1 1
1 2 4 8
2 3 9 27
3 4 16 64
这 非常 接近您所拥有的,但这些列需要存在才能 df.loc
工作。
对于外行来说,df.loc 有两个参数,一个是您要处理的行列表 - 在本例中 :
表示所有行,另一个是列列表 - ['x_squared', 'x_cubed']
.
这适用于正数。考虑如何概括,但这个解决方案的简洁让我分心了。
df = pd.DataFrame(range(1, 10))
a = np.arange(1, 4).reshape(1, -1)
np.exp(np.log(df).dot(a))
我知道我可以向数据框添加一列并将其值更新为从函数返回的值,如下所示:
df=pd.DataFrame({'x':[1,2,3,4]})
def square(x):
return x*x
df['x_squared'] = [square(i) for i in df['x']]
但是,我遇到了实际函数返回两项的问题,我想将这两项放在两个不同的新列中。我在这里写了一个伪代码来更清楚地描述我的问题:
df=pd.DataFrame({'x':[1,2,3,4]})
def squareAndCube(x):
return x*x, x*x*x
#below is a pseudo-code
df['x_squared'], df['x_cubed'] = [squareAndCube(i) for i in df['x']]
上面的代码给我一条错误消息说 "too many values to unpack"。 那么,我应该如何解决这个问题?
你可以用矢量化的方式来做,像这样 -
df['x_squared'], df['x_cubed'] = df.x**2,df.x**3
或者像这样使用自定义函数 -
df['x_squared'], df['x_cubed'] = squareAndCube(df.x)
回到你的循环案例,在作业的右侧,你有:
In [101]: [squareAndCube(i) for i in df['x']]
Out[101]: [(1, 1), (4, 8), (9, 27), (16, 64)]
现在,在左侧,您有 df['x_squared'], df['x_cubed'] =
。因此,它期望所有行的平方数作为第一个输入分配。从上面显示的列表中,第一个元素不是那个,它实际上是第一行的正方形和立方体。因此,解决方法是 "transpose" 列出并指定为新列。因此,修复将是 -
In [102]: L = [squareAndCube(i) for i in df['x']]
In [103]: map(list, zip(*L)) # Transposed list
Out[103]: [[1, 4, 9, 16], [1, 8, 27, 64]]
In [104]: df['x_squared'], df['x_cubed'] = map(list, zip(*L))
为了 NumPy broadcasting
的爱!
df['x_squared'], df['x_cubed'] = (df.x.values[:,None]**[2,3]).T
这样使用 df.loc
怎么样:
df=pd.DataFrame({'x':[1,2,3,4]})
def square(x):
return x*x
df['x_squared'] = df['x_cubed'] = None
df.loc[:, ['x_squared', 'x_cubed']] = [squareAndCube(i) for i in df['x']]
给予
x x_squared x_cubed
0 1 1 1
1 2 4 8
2 3 9 27
3 4 16 64
这 非常 接近您所拥有的,但这些列需要存在才能 df.loc
工作。
对于外行来说,df.loc 有两个参数,一个是您要处理的行列表 - 在本例中 :
表示所有行,另一个是列列表 - ['x_squared', 'x_cubed']
.
这适用于正数。考虑如何概括,但这个解决方案的简洁让我分心了。
df = pd.DataFrame(range(1, 10))
a = np.arange(1, 4).reshape(1, -1)
np.exp(np.log(df).dot(a))