繁体   English   中英

根据pandas DataFrame中的列值有条件地替换多个列

[英]Conditional replacement of multiple columns based on column values in pandas DataFrame

提示:本站提供中英文对照查看,鼠标放在中文字句上可显示英文原文。 若本文未解决您的问题,推荐您尝试使用帮您解决。

我想基于第一组列中的值(具体地,第一列中的一列为空白),同时将多列的值替换为其他列中的对应值。 这是我正在尝试做的一个例子:

import pandas as pd

df = pd.DataFrame({'a1':['m', 'n', 'o', 'p'],
                   'a2':['q', 'r', 's', 't'],
                   'b1':['',  '',  'a', '' ],
                   'b2':['',  '',  'b',  '']})

df

#   a1 a2 b1 b2
# 0  m  q
# 1  n  r
# 2  o  s  a  b
# 3  p  t

我想将b1和b2中的''值替换为a1和a2中的相应值,其中b1为空:

#   a1 a2 b1 b2
# 0  m  q  m  q
# 1  n  r  n  r
# 2  o  s  a  b
# 3  p  t  p  t

这是我的思考过程(我对熊猫来说相对较新,所以我可能会说这里有一个很重的R口音):

missing = (df.b1 == '')

# First thought:
df[missing, ['b1', 'b2']] = df[missing, ['a1', 'a2']]
# TypeError: 'Series' objects are mutable, thus they cannot be hashed

# Fair enough  
df[tuple(missing), ('b1', 'b2')] = df[tuple(missing), ('a1', 'a2')]
# KeyError: ((True, True, False, True), ('a1', 'a2'))

# Obviously I'm going about this wrong.  Maybe I need to use indexing?
df[['b1', 'b2']].ix[missing,:]
#   b1 b2
# 0      
# 1      
# 3      

# That looks right
df[['b1', 'b2']][missing, :] = df[['a1', 'a2']].ix[missing, :]
# TypeError: 'Series' objects are mutable, thus they cannot be hashed
# Deja vu

df[['b1', 'b2']].ix[tuple(missing), :] = df[['a1', 'a2']].ix[tuple(missing), :]
# ValueError: could not convert string to float:
# Uhh...

我可以逐列完成:

df['b1'].ix[missing] = df['a1'].ix[missing]
df['b2'].ix[missing] = df['a2'].ix[missing]

...但我怀疑这是一种更惯用的方法。 思考?

更新:为了澄清,我特别想知道是否所有列都可以同时更新。 例如,对Primer答案的假设修改(这不起作用并导致NaN,尽管我不确定为什么):

df.loc[missing, ['b1', 'b2']] = f.loc[missing, ['a1', 'a2']]

#   a1 a2   b1   b2
# 0  m  q  NaN  NaN
# 1  n  r  NaN  NaN
# 2  o  s    a    b
# 3  p  t  NaN  NaN

怎么样

df[['b1', 'b2']] = df[['b1', 'b2']].where(df[['b1', 'b2']] != '', df[['a1', 'a2']].values)

这回来了

  a1 a2 b1 b2
0  m  q  m  q
1  n  r  n  r
2  o  s  a  b
3  p  t  p  t

你可以这样做:

mask1 = df.b1.str.len() == 0
mask2 = df.b2.str.len() == 0
df.loc[mask1, 'b1'] = df.loc[mask1, 'a1']
df.loc[mask2, 'b2'] = df.loc[mask2, 'a2']
print df

  a1 a2 b1 b2
0  m  q  m  q
1  n  r  n  r
2  o  s  a  b
3  p  t  p  t

或者像这样的面具也会起作用:

mask1 = df.b1 == ''
mask2 = df.b2 == ''

怎么样:

missing = df.loc[:] == ""
shifted = df.copy().shift(2, axis=1)
df[missing] = shifted

换句话说,构造missing数据的单元格的missing布尔掩码,以及所有列向右移动两个位置的原始数据的副本。 然后将移位的数据分配给原始数据,但仅限于原始数据丢失的位置。

数据会像这样流动:

数据进展

仅复制missing绿色的单元格。

如果你想在一行中完成这一切,那么可行,如果你不清楚为什么要做各种操作:

df[df.loc[:] == ""] = df.copy().shift(2, axis=1)
问题未解决?试试使用:帮您解决问题。
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM