将一种方法应用于Pandas数据框中几个选定的列

5
我想对Dataframe中的几列应用一个小方法。方法color_negative不能应用于包含字符串的列,因此我需要以某种方式跳过这些列。我可以想到两种方法来解决这个问题,但可悲的是都没有起作用。
在第一种方法中: 我尝试使用Dataframe的索引和将while循环的递增计数器设置为1,逐个跳过第一列,然后对每一列应用该方法。当执行此方法时,我会得到错误,即'Series'对象没有'style'属性,因此显然无法将方法应用于单个列。
在第二种方法中: 我尝试使用subset仅将该方法应用于具有数字值的列,但我不确定是否正确使用了subset。当执行此方法时,我会得到错误,即类型为'Styler'的对象没有len()。
下面是一个简化的示例:
import pandas as pd

d = {'col1': ['a', 'b'], 'col2': [21, 22], 'col3': [3, 51]}
df = pd.DataFrame(data=d)

def color_negative_red(val):
    color = 'black'
    if val < -1 : color = 'red'
    if val > 1 :  color = 'green'
    return 'color: %s' % color    
    
i=1
while i <= len(df):
    #Approach 1
    df.iloc[:, i] = df.iloc[:, i].style.applymap(color_negative_red)
    #Approach 2
    df = df.style.applymap(color_negative_red, subset = df.iloc[:, i])
    i+=1    

df

有人有解决这个问题的建议吗?


1
你可以使用 df.select_dtype 函数来获取特定数据类型的列,例如 df.select_dtype(include=np.number) - Scott Boston
或者 df._get_numeric_data() - sacuL
谢谢大家,那样做可以了。 - BlueBerry
3个回答

4
您可以选择所需列,然后对它们使用applymap,具体操作如下:
column_names = ['name_a','name_b']
df[column_names] = df[column_names].applymap(my_func)

如果您愿意,可以过滤掉字符串类型的列。

from numpy.core.multiarray import dtype

column_names = [name for name,col_type in df.dtypes.items() if col_type!=dtype('O')]

我尝试按照你建议的手动操作,它可以工作,但是我的列数很多,我想要一种更有效/优雅的方法来应用这种方法。这就是为什么我尝试使用索引和while循环的原因。 - BlueBerry

2
您可以使用DataFrame of stylesnumpy.select来填充,同时使用style.Styler.apply
d = {'col1': ['a', 'b'], 'col2': [21, 22], 'col3': [0, -51]}
df = pd.DataFrame(data=d)

def color_negative_red(x):
    #select only numeric columns
    x1 = x.select_dtypes(np.number)
    c1 = 'color: red'
    c2 = 'color: green'
    c3 = '' 
    #boolean masks
    m1 = x1 < -1
    m2 = x1 > 1
    #numpy array by conditions
    arr = np.select([m1, m2], [c1, c2], default=c3)
    df1 =  pd.DataFrame(arr, index=df.index, columns=x1.columns)
    #added strings columns filled by c3 string 
    df1 = df1.reindex(columns=x.columns, fill_value=c3)
    return df1

df.style.apply(color_negative_red, axis=None)

pic


0

将您的函数向量化

import numpy as np

f = np.vectorize(color_negative_red)

然后您可以使用简单的apply,同时按所需的列名进行过滤:

df.apply(lambda x: f(x) if x.name not in ['col1'] else x)
#   col1          col2          col3
# 0    a  color: green  color: green
# 1    b  color: green  color: green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接