Панды: применить функцию, осведомленную о типе столбца, к каждому столбцу фрейма данных - PullRequest
0 голосов
/ 22 сентября 2018

Цель

Я хотел бы применить функцию, которая зависит от типа входного столбца, к каждому столбцу во фрейме данных.Рассмотрим следующий фрейм данных:

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

1 Ответ

0 голосов
/ 22 сентября 2018

Если у вас есть список разрешенных типов, просто используйте 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 в качествеparent dtype, если вы хотите выбрать только столбцы с числами.

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

Конечно, вы можете изменить [np.number] на ваш список allowed_types, если вам действительно нужно быть конкретным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...