分配列'来自Pandas数据帧中其他列的值

时间:2015-01-26 23:37:44

标签: python pandas

如果/ where条件满足,我如何将数据框中的列分配给另一列?

更新
问题
当满足条件时,我需要分配许多列值(有时是该行中另一列的值)
条件不是问题。

我需要一种有效的方法来做到这一点:

df.loc[some condition it doesn't matter,
['a','b','c','d','e','f','g','x','y']]=df['z'],1,3,4,5,6,7,8,df['p']

简化示例数据

d = {'var' : pd.Series([10,61]),
'c' : pd.Series([100,0]),
'z' : pd.Series(['x','x']),
'y' : pd.Series([None,None]),
'x' : pd.Series([None,None])}
df=pd.DataFrame(d)
如果var没有丢失且第一个数字小于5,则

条件 结果 make df.x = df.z& df.y = 1

这是伪造的代码,它不起作用,但这正是我想要的。

df.loc[((df['var'].dropna().astype(str).str[0].astype(int) < 5)),
['x','y']]=df['z'],1

但是我得到了

ValueError:无法使用长度与值

不同的类似列表的索引器进行设置

理想输出

     c  var     x     z     y
0  100    10    x     x     1
1    0    61    None  x  None

下面的代码有效,但效率太低,因为我需要为多列分配值。

df.loc[((df['var'].dropna().astype(str).str[0].astype(int) < 5)),
['x']]=df['z']
df.loc[((df['var'].dropna().astype(str).str[0].astype(int) < 5)),
['y']]=1

2 个答案:

答案 0 :(得分:2)

这是一种方法:

import pandas as pd
import numpy as np

d = {'var' : pd.Series([1,6]),
'c' : pd.Series([100,0]),
'z' : pd.Series(['x','x']),
'y' : pd.Series([None,None]),
'x' : pd.Series([None,None])}
df = pd.DataFrame(d)

# Condition 1: if var is not missing
cond1 = ~df['var'].apply(np.isnan)
# Condition 2: first number is less than 5
cond2 = df['var'].apply(lambda x: int(str(x)[0])) < 5
mask = cond1 & cond2
df.ix[mask, 'x'] = df.ix[mask, 'z']
df.ix[mask, 'y'] = 1
print df

输出:

     c  var     x     y  z
0  100    1     x     1  x
1    0    6  None  None  x

如您所见,布尔掩码必须应用于赋值的两侧,您需要在1列上广播值y。将步骤分成多行可能更简洁。

问题已更新,编辑:更一般地说,由于某些分配取决于其他列,而某些分配只是沿着列进行广播,因此您可以分两步完成:

df.loc[conds, ['a','y']] = df.loc[conds, ['z','p']]
df.loc[conds, ['b','c','d','e','f','g','x']] = [1,3,4,5,6,7,8]

您可以查看并查看这是否足以满足您的使用案例。

答案 1 :(得分:2)

你可以按行工作:

def f(row):
    if row['var'] is not None and int(str(row['var'])[0]) < 5:
        row[['x', 'y']] = row['z'], 1
    return row

>>> df.apply(f, axis=1)
     c  var     x   y  z
0  100   10     x   1  x
1    0   61  None NaN  x

覆盖原始df:

df = df.apply(f, axis=1)