панды, умножьте все числовые значения в фрейме данных на константу

как умножить все числовые значения в фрейме данных на константу без явного указания имен столбцов? Пример:

In [13]: df = pd.DataFrame({'col1': ['A','B','C'], 'col2':[1,2,3], 'col3': [30, 10,20]})

In [14]: df
Out[14]: 
  col1  col2  col3
0    A     1    30
1    B     2    10
2    C     3    20

пробовал df.multiply но это также влияет на строковые значения, объединяя их несколько раз.

In [15]: df.multiply(3)
Out[15]: 
  col1  col2  col3
0  AAA     3    90
1  BBB     6    30
2  CCC     9    60

есть ли способ сохранить строковые значения нетронутыми при умножении только числовых значений на константу?

4 ответов


можно использовать select_dtypes() в том числе number dtype или исключая все столбцы object и datetime64 dtypes:

демо:

In [162]: df
Out[162]:
  col1  col2  col3       date
0    A     1    30 2016-01-01
1    B     2    10 2016-01-02
2    C     3    20 2016-01-03

In [163]: df.dtypes
Out[163]:
col1            object
col2             int64
col3             int64
date    datetime64[ns]
dtype: object

In [164]: df.select_dtypes(exclude=['object', 'datetime']) * 3
Out[164]:
   col2  col3
0     3    90
1     6    30
2     9    60

или гораздо лучшее решение (c) Айхан:

df[df.select_dtypes(include=['number']).columns] *= 3

С docs:

для выбора всех числовых типов используйте numpy dtype numpy.номер


одним из способов было бы получить dtypes, сопоставьте их с object и datetime dtypes и исключить их с помощью маски, например -

df.ix[:,~np.in1d(df.dtypes,['object','datetime'])] *= 3

образец выполнения -

In [273]: df
Out[273]: 
  col1  col2  col3
0    A     1    30
1    B     2    10
2    C     3    20

In [274]: df.ix[:,~np.in1d(df.dtypes,['object','datetime'])] *= 3

In [275]: df
Out[275]: 
  col1  col2  col3
0    A     3    90
1    B     6    30
2    C     9    60

другой ответ указывает, как умножать только числовые столбцы. Вот как его обновить:

df = pd.DataFrame({'col1': ['A','B','C'], 'col2':[1,2,3], 'col3': [30, 10,20]})

s = df.select_dtypes(include=[np.number])*3

df[s.columns] = s

print (df)

  col1  col2  col3
0    A     3    90
1    B     6    30
2    C     9    60

Это должно работать даже над смешанными типами в столбцах, но, вероятно, медленно над большими кадрами данных.

def mul(x, y):
    try:
        return pd.to_numeric(x) * y
    except:
        return x

df.applymap(lambda x: mul(x, 3))