如何在没有循环的情况下将多个Pandas DF列更改为分类

Pab*_*cia 6 python numpy categorization dataframe pandas

我有一个DataFrame,我想将几​​个列从'object'类型更改为'category'.

我可以同时更改几列用于浮动,

dftest[['col3', 'col4', 'col5', 'col6']] = \
    dftest[['col3', 'col4', 'col5', 'col6']].astype(float)
Run Code Online (Sandbox Code Playgroud)

对于'类别'我不能这样做,我需要一个接一个地做(或像这里一样循环).

for col in ['col1', 'col2']:
    dftest[col] = dftest[col].astype('category')
Run Code Online (Sandbox Code Playgroud)

问题:是否有任何方法可以像"浮动"示例一样对所有想要的列进行更改?

如果我尝试同时做几个列,我有:

dftest[['col1','col2']] = dftest[['col1','col2']].astype('category')
## NotImplementedError: > 1 ndim Categorical are not supported at this time
Run Code Online (Sandbox Code Playgroud)

我目前的工作测试代码:

import numpy as np
import pandas as pd 

factors= np.array([
        ['a', 'xx'],
        ['a', 'xx'],
        ['ab', 'xx'],
        ['ab', 'xx'],
        ['ab', 'yy'],
        ['cc', 'yy'],
        ['cc', 'zz'],
        ['d', 'zz'],
        ['d', 'zz'],
        ['g', 'zz'] 
        ])

values = np.random.randn(10,4).round(2)

dftest = pd.DataFrame(np.hstack([factors,values]), 
                  columns = ['col1', 'col2', 'col3', 'col4', 'col5', 'col6'])

#dftest[['col1','col2']] = dftest[['col1','col2']].astype('category')
## NotImplementedError: > 1 ndim Categorical are not supported at this time

## it works with individual astype
#dftest['col2'] = dftest['col2'].astype('category')
#dftest['col1'] = dftest['col1'].astype('category')

print(dftest)

## doing a loop
for col in ['col1', 'col2']:
    dftest[col] = dftest[col].astype('category')


dftest[['col3', 'col4', 'col5', 'col6']] = \
    dftest[['col3', 'col4', 'col5', 'col6']].astype(float)

dftest.dtypes
Run Code Online (Sandbox Code Playgroud)

输出:

col1    category
col2    category
col3     float64
col4     float64
col5     float64
col6     float64
dtype: object
Run Code Online (Sandbox Code Playgroud)

== [更新] ==

我现在知道诀窍我没有使用循环的问题,但是我问了这个问题,因为我想学习/理解为什么我需要为'类别'做一个循环而不是浮动,如果没有其他的这样做的方式.

ptr*_*trj 3

目前还不清楚 的结果dftest[['col1','col2']].astype('category')应该是什么,即结果列是否应该共享相同的类别。

循环列使每列都有一组单独的类别。(我相信这是您的示例中期望的结果。)

另一方面,.astype(float)工作方式有所不同:它将基础值分解为一维数组,将其转换为浮点数,然后将其重新整形回原始形状。这样,它可能比仅仅迭代列更快。category您可以使用更高级别的函数来模拟此行为:

result = dftest[['col1', 'col2']].stack().astype('category').unstack()
Run Code Online (Sandbox Code Playgroud)

但随后您会得到两列共享的一组类别:

result['col1']
Out[36]: 
0     a
1     a
2    ab
3    ab
4    ab
5    cc
6    cc
7     d
8     d
9     g
Name: col1, dtype: category
Categories (8, object): [a < ab < cc < d < g < xx < yy < zz]
Run Code Online (Sandbox Code Playgroud)