pandas将数据帧值替换为同一行中的其他列值

时间:2017-02-07 14:57:25

标签: python pandas dataframe replace

我有这个pandas数据帧

BU       |   DATA1      DATA2
01-TT        zone 01   noData
02-FF        noData    zone 02
....

我需要用BU列中的相应行替换“noData”字符串,但只使用两个第一个字符并添加“zone”字

BU       |   DATA1      DATA2
01-TT        zone 01    zone 01
02-FF        zone 02    zone 02
....

非常感谢

2 个答案:

答案 0 :(得分:2)

一般解决方案:

In [135]:
cols = df.columns[df.columns.str.contains('DATA')]
df[cols] = df[cols].mask(df[cols].apply(lambda x: x.str.contains('noData')), 'zone ' + df['BU'].str[:2], axis=0)
df

Out[135]:
      BU    DATA1    DATA2
0  01-TT  zone 01  zone 01
1  02-FF  zone 02  zone 02

这里我们首先确定包含DATA的cols,然后我们只在这些cols上调用mask并使用布尔掩码,只替换满足条件的那些行并覆盖

答案 1 :(得分:1)

您可以使用mask替换由numpy.repeat创建的True替换numpy array的值:

df = df.set_index('BU')

arr = np.repeat('zone ' + df.index.str[:2], len(df.columns)).values.reshape(df.shape)
print (arr)
[['zone 01' 'zone 01']
 ['zone 02' 'zone 02']]

df = df.mask(df == 'noData', arr)
print (df.reset_index())
      BU    DATA1    DATA2
0  01-TT  zone 01  zone 01
1  02-FF  zone 02  zone 02

<强>计时

#[20000 rows x 3 columns]
df = pd.concat([df]*10000).reset_index(drop=True)
print (df)

df1 = df.copy()

def jez(df):
    df = df.set_index('BU')
    df = df.mask(df == 'noData', np.repeat('zone ' + df.index.str[:2], len(df.columns)).values.reshape(df.shape))
    return (df.reset_index())

def ed(df):
    cols = df.columns[df.columns.str.contains('DATA')]
    df[cols] = df[cols].mask(df[cols].apply(lambda x: x.str.contains('noData')), 'zone ' + df['BU'].str[:2], axis=0)
    return df


print (jez(df))
print (ed(df1))

In [219]: %timeit (jez(df))
100 loops, best of 3: 14.2 ms per loop

In [220]: %timeit (ed(df1))
10 loops, best of 3: 46.3 ms per loop