Цель
Я хотел бы применить функцию, которая зависит от типа входного столбца, к каждому столбцу во фрейме данных.Рассмотрим следующий фрейм данных:
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
Кроме тогок длине и отсутствию я хотел бы добавить третью строку в description_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