熊猫:将了解列类型的函数应用于数据框的每一列

时间:2018-09-21 22:02:12

标签: python pandas lambda types

目标

我想将取决于输入列类型的函数应用于数据帧中的每一列。考虑以下数据帧:

df = pd.DataFrame( [["a",1],["b",2]], columns = ["string","num"] )

我可以测试列的类型:

>>> df["num"].dtype            
dtype('int64')
>>> df["num"].dtype in ["int64"]
True

我可以在所有列上应用一个函数:

>>> df . apply( lambda column: column.sum() )
string    ab
num        3
dtype: object

但是,如果我使函数取决于列的类型,则会出现垃圾:

>>> df . apply( lambda column:
...             np.nan if not column.dtype in ['float64','float32','int32','int64']
...             else column.sum() )
string   NaN
num      NaN
dtype: float64

动机

有些解决方案主要涉及删除非数字列,但实际上我需要保留它们。这样做的原因是我试图在df.describe的结果中追加一个对每一列中的零进行计数的行。这是类似功能的示例:

def describe_plus(df):
  most_stats = df.describe()
  missing_stat = pd.DataFrame( df.isnull().sum()
                             , columns = ["missing"]
                             ).transpose()
  length_stat = pd.DataFrame( [[len(df) for _ in df.columns]]
                            , index = ["length"]
                            , columns = df.columns )
  return length_stat.append( missing_stat.append( most_stats ) )

该调用可为您提供pd.describe的普通输出,以及每列中缺少的长度和数字:

>>> describe_plus( df )
              num  string
length   2.000000     2.0
missing  0.000000     0.0
count    2.000000     NaN
mean     1.000000     NaN
std      1.414214     NaN
min      0.000000     NaN
25%      0.500000     NaN
50%      1.000000     NaN
75%      1.500000     NaN
max      2.000000     NaN

除了长度和缺失之外,我还要在describe_plus中添加第三行,该行计算每列中零的数量,或者为非数字的列提供NaN。

编辑:在此框架中RafaelC的解决方案

诀窍是丢弃那些非数字变量,计算汇总统计信息,然后简单地附加其他统计信息(定义在每一列,甚至是非数字统计信息上)。

def describe_plus_plus(df):
  nums = df.select_dtypes(include=[np.number])
  zeroes = pd.DataFrame( [nums.apply( lambda col: len( col[col==0] ) / 
len(nums) )] )
  return zeroes.append( describe_plus( df ) )

实例:

>>> df = pd.DataFrame( [[0,0,0,""],[0,0,1,"a"],[0,1,2,"b"]], columns = ["none","1/3","2/3","string"] )
>>> describe_plus_plus( df )
              1/3       2/3  none  string
0        0.666667  0.333333   1.0     NaN
length   3.000000  3.000000   3.0     3.0
missing  0.000000  0.000000   0.0     0.0
count    3.000000  3.000000   3.0     NaN
mean     0.333333  1.000000   0.0     NaN
std      0.577350  1.000000   0.0     NaN
min      0.000000  0.000000   0.0     NaN
25%      0.000000  0.500000   0.0     NaN
50%      0.000000  1.000000   0.0     NaN
75%      0.500000  1.500000   0.0     NaN
max      1.000000  2.000000   0.0     NaN

1 个答案:

答案 0 :(得分:2)

如果您有允许的类型列表,只需使用loc

allowed_types = [np.float64, np.float32,np.int32, np.int64]
mask = df.dtypes.isin(allowed_types)
df.loc[:, mask].sum()

但是,一种可能更好的方法是使用select_dtypes,如果只想选择数字列,则使用np.number作为父dtype。

df.select_dtypes(include=[np.number])

当然,如果确实需要具体说明,可以将[np.number]更改为allowed_types的列表。