for循环中的dataframe.replace()

时间:2017-03-12 23:21:07

标签: python pandas dataframe

我正在尝试替换num列中的值。对于ab中的每个字母,我都有一本字典。我在下面只显示了两个(A& B)

data = pd.DataFrame( {'ab' : ['A','B','A','A','B'], 'num' : ['01','02','01','01','01']})

a_replacements = { 'num' : { '01' : 'funny', '02' : 'serious' }}
b_replacements = { 'num' : { '01' : 'beginning', '02' : 'end' }}

data[data.ab == 'A'] = data[data.ab == 'A'].replace(inplace=True, to_replace=a_replacements)

最后一行的作业正常。但是当我尝试在for循环中使用它时,我必须在num中替换ab中26个不同字母的值,我面临以下问题:

for letter in data.ab.unique():
    data.loc[data.ab == letter] = data.replace(to_replace=letter.lower()+"_replacements")

我得到了:

TypeError                                 Traceback (most recent call last)
<ipython-input-96-acd3197ceef4> in <module>()
      1 for letter in data.ab.unique():
      2     print(letter.lower()+"_replacements")
----> 3     data.loc[data.ab == letter] = data.replace(to_replace=letter.lower()+"_replacements")

/Users/alokshenoy/.pyenv/versions/miniconda3-latest/lib/python3.6/site-packages/pandas/core/generic.py in replace(self, to_replace, value, inplace, limit, regex, method, axis)
   3427             if isinstance(to_replace, (tuple, list)):
   3428                 return _single_replace(self, to_replace, method, inplace,
-> 3429                                        limit)
   3430 
   3431             if not is_dict_like(to_replace):

/Users/alokshenoy/.pyenv/versions/miniconda3-latest/lib/python3.6/site-packages/pandas/core/generic.py in _single_replace(self, to_replace, method, inplace, limit)
     70     if self.ndim != 1:
     71         raise TypeError('cannot replace {0} with method {1} on a {2}'
---> 72                         .format(to_replace, method, type(self).__name__))
     73 
     74     orig_dtype = self.dtype

TypeError: cannot replace ['a_replacements'] with method pad on a DataFrame

关于如何解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:1)

问题的解决方案在groupby。这将允许您处理使用唯一替换的每个组。

密码:

for name, group in data.groupby(['ab']):
    data[data.ab == name] = group.replace(to_replace=replacements[name])

所有代码:

import pandas as pd

data = pd.DataFrame({'ab': ['A', 'B', 'A', 'A', 'B'],
                     'num': ['01', '02', '01', '01', '01']})
print(data)

replacements = dict(
    A={'num': {'01': 'funny', '02': 'serious'}},
    B={'num': {'01': 'beginning', '02': 'end'}},
)

for name, group in data.groupby(['ab']):
    data[data.ab == name] = group.replace(to_replace=replacements[name])

print(data)

<强>结果:

  ab num
0  A  01
1  B  02
2  A  01
3  A  01
4  B  01

  ab        num
0  A      funny
1  B        end
2  A      funny
3  A      funny
4  B  beginning

答案 1 :(得分:1)

您可以将groupbyapply一起使用,以替换zip创建的所有词组的dict,将ab列中的名称列表映射到词典列表:

a_replacements = { 'num' : { '01' : 'funny', '02' : 'serious' }}
b_replacements = { 'num' : { '01' : 'beginning', '02' : 'end' }}
abnames = ['A','B']
L = [a_replacements, b_replacements]

replacements = dict(zip(abnames, L))
print (replacements)
{'A': {'num': {'01': 'funny', '02': 'serious'}}, 
'B': {'num': {'01': 'beginning', '02': 'end'}}}

df = data.groupby('ab').apply(lambda x: x.replace(replacements[x.name]))
print (df)
  ab        num
0  A      funny
1  B        end
2  A      funny
3  A      funny
4  B  beginning