繁体   English   中英

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

[英]Pandas: Apply a function aware of column type to every column of a data frame

目标

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

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

如果您有允许的类型列表,只需使用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作为父np.number

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

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

暂无
暂无

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

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