Pandas 应用并映射到每列的每个元素

ds_*_*ser 4 python python-2.7 pandas pandas-apply

如果值不为空,如何将自定义函数应用于每列的每个元素?

假设我有一个 10 列的数据框,如果 pd.notnull(x),我想将 lower() 函数应用于仅 4 列的每个元素,否则只保留 None 作为值。

我尝试这样使用,

s.apply(lambda x: change_to_lowercase(x), axis = 1)

def change_to_lowercase(s):

    s['A'] =  s['A'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['B'] = s['B'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['C'] = s['C'].map(lambda x: x.lower() if pd.notnull(x) else x)
    s['D'] = s['D'].map(lambda x: x.lower() if pd.notnull(x) else x)
    return s
Run Code Online (Sandbox Code Playgroud)

但由于我的列是混合数据类型(NaN 作为 float,其余为 unicode)。这给我带来了一个错误 -

float has no attribute map.
Run Code Online (Sandbox Code Playgroud)

如何摆脱这个错误?

jez*_*ael 5

我认为你需要DataFrame.applymap因为按元素工作:

L = [[1.5, 'Test', np.nan, 2], ['Test', np.nan, 2,'TEST'], ['Test', np.nan,1.5,  2]]
df = pd.DataFrame(L, columns=list('abcd'))
print (df)

      a     b    c     d
0   1.5  Test  NaN     2
1  Test   NaN  2.0  TEST
2  Test   NaN  1.5     2

cols = ['a','b']
#for python 2 change str to basestring
df[cols] = df[cols].applymap(lambda x: x.lower() if isinstance(x, str) else x)
print (df)
      a     b    c     d
0   1.5  test  NaN     2
1  test   NaN  2.0  TEST
2  test   NaN  1.5     2
Run Code Online (Sandbox Code Playgroud)