Pandas:类别数据类型和过滤器
Pandas: category dtype and filter
使用 pandas 0.18.1,我在过滤 dtype
为 category
的列时实现了不同的行为。这是一个最小的例子。
import pandas as pd
import numpy as np
l = np.random.randint(1, 4, 50)
df = pd.DataFrame(dict(c_type=l, i_type=l))
df['c_type'] = df.c_type.astype('category')
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50 entries, 0 to 49
Data columns (total 2 columns):
c_type 50 non-null category
i_type 50 non-null int64
dtypes: category(1), int64(1)
memory usage: 554.0 bytes
过滤掉其中一个整数类型列的值导致
df[df.i_type.isin([1, 2])].i_type.value_counts()
2 20
1 17
Name: i_type, dtype: int64
但对类别类型列的相同过滤会将值过滤为条目
df[df.c_type.isin([1, 2])].c_type.value_counts()
2 20
1 17
3 0
Name: c_type, dtype: int64
虽然过滤器有效,但我觉得这种行为很不正常。例如,过滤器可用于从 pivot_table
函数中排除未来的列,这在处理 category
时需要额外的过滤器。
这是预期的行为吗?
这是预期的行为,如果检查 categorical docs:
Series methods like Series.value_counts() will use all categories, even if some categories are not present in the data:
In [100]: s = pd.Series(pd.Categorical(["a","b","c","c"], categories=["c","a","b","d"]))
In [101]: s.value_counts()
Out[101]:
c 2
b 1
a 1
d 0
dtype: int64
因此,如果按 5
过滤(值不存在),每个类别都会得到 0
:
print (df[df.c_type.isin([5])].c_type.value_counts())
3 0
2 0
1 0
Name: c_type, dtype: int64
使用 pandas 0.18.1,我在过滤 dtype
为 category
的列时实现了不同的行为。这是一个最小的例子。
import pandas as pd
import numpy as np
l = np.random.randint(1, 4, 50)
df = pd.DataFrame(dict(c_type=l, i_type=l))
df['c_type'] = df.c_type.astype('category')
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 50 entries, 0 to 49
Data columns (total 2 columns):
c_type 50 non-null category
i_type 50 non-null int64
dtypes: category(1), int64(1)
memory usage: 554.0 bytes
过滤掉其中一个整数类型列的值导致
df[df.i_type.isin([1, 2])].i_type.value_counts()
2 20
1 17
Name: i_type, dtype: int64
但对类别类型列的相同过滤会将值过滤为条目
df[df.c_type.isin([1, 2])].c_type.value_counts()
2 20
1 17
3 0
Name: c_type, dtype: int64
虽然过滤器有效,但我觉得这种行为很不正常。例如,过滤器可用于从 pivot_table
函数中排除未来的列,这在处理 category
时需要额外的过滤器。
这是预期的行为吗?
这是预期的行为,如果检查 categorical docs:
Series methods like Series.value_counts() will use all categories, even if some categories are not present in the data:
In [100]: s = pd.Series(pd.Categorical(["a","b","c","c"], categories=["c","a","b","d"]))
In [101]: s.value_counts()
Out[101]:
c 2
b 1
a 1
d 0
dtype: int64
因此,如果按 5
过滤(值不存在),每个类别都会得到 0
:
print (df[df.c_type.isin([5])].c_type.value_counts())
3 0
2 0
1 0
Name: c_type, dtype: int64