[英]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。
訣竅是丟棄那些非數字變量,計算匯總統計信息,然后簡單地附加其他統計信息(這些統計信息是在每一列上定義的,甚至是非數字的)。
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.