深入浅出Pandas读书笔记
要实现基础的透视操作, 可以使用df.pivot()返回按给定的索引, 列值重新组织整理后的DataFrame. df.pivot()有3个参数, 这些参数传入的值是原数据的列名, 作用分别为
df = pd.DataFrame({"A": ['a1', 'a1', 'a2', 'a3', 'a3', 'a3'],
'B': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3'],
'C': ['c1', 'c2', 'c3', 'c4', 'c5', 'c6'],
'D': ['d1', 'd2', 'd3', 'd4', 'd5', 'd6'],
})
df.pivot(index='A', columns='B', values='C') # A与B没有重复值, 将A列去重作为索引, B列去重作为列, 取C的内容作为具体的数据值
'''
B b1 b2 b3
A
a1 c1 c2 NaN
a2 NaN NaN c3
a3 c4 c5 c6
'''
df.pivot()只是对原数据的结构, 显示做了变换, 在实现业务中, 往往还需要在数据透视过程中对值进行计算, 这时候就要用到pd.pivot_table()
pd.pivot_table()有以下几个关键参数
df = pd.DataFrame({"A": ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
'B': ['b2', 'b2', 'b1', 'b1', 'b1', 'b1'],
'C': ['c1', 'c1', 'c2', 'c2', 'c1', 'c1'],
'D': [1, 2, 3, 4, 5, 6],
})
# 如果对以上数据进行以A为索引, 以B为列的透视df.pivot(), 会报错, 因为索引和列组合后有重复数据, 涉及到聚合操作, 需要使用pd.pivot_table()
df.pivot_table(index='A', columns='B', values='D') # 默认求mean
df.pivot_table(index=['A', 'B'], columns='C', values='D', aggfunc=np.sum, fill_value=0, margins=True)
# 使用多个计算方法
df.pivot_table(index=['A', 'B'], columns='C', values='D', aggfunc=[np.mean, np.sum])
# 为每一列指定不同的计算方法
df = pd.DataFrame({
'A': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'],
'B': ['b2', 'b2', 'b1', 'b1', 'b1', 'b1'],
'C': ['c1', 'c1', 'c2', 'c2', 'c1', 'c1'],
'D': [1, 2, 3, 4, 5, 6],
'E': [9, 8, 7, 6, 5, 4]
})
df.pivot_table(index=['A', 'B'], columns='C', aggfunc={'D': np.mean, 'E': np.sum})
df.pivot_table(index=['A', 'B'], columns='C', aggfunc={'D': [np.mean], 'E': np.sum}) # 在aggfunc内的函数中加入[], 在现实中会把函数名显示出
堆叠stack的过程表示将数据列的所有数据表全部旋转到列上
解堆unstack的过程表示将在行上的索引旋转到列上
df = pd.DataFrame({
'A': ['a1', 'a1', 'a2', 'a2'],
'B': ['b1', 'b2', 'b1', 'b2'],
'C': [1, 2, 3, 4],
'D': [5, 6, 7, 8],
'E': [5, 6, 7, 8]
})
df.set_index(['A', 'B'], inplace=True)
df.stack()
'''
A B
a1 b1 C 1
D 5
E 5
b2 C 2
D 6
E 6
a2 b1 C 3
D 7
E 7
b2 C 4
D 8
E 8
dtype: int64
'''
type(df.stack()) # pandas.core.series.Series
df.stack().unstack()
'''
C D E
A B
a1 b1 1 5 5
b2 2 6 6
a2 b1 3 7 7
b2 4 8 8
'''
交叉表就是将两列或多列中不重复的元素组成一个新的DataFrame, 新数据的行和列交叉部分的值为其组合在原数据中的数量
pd.crosstab(index, columns, values=None, rownames=None, colnames=None, aggfunc=None, margins=False,
margins_name: str='All', dropna: bool=True, normalize=False
)
参数说明如下
df = pd.DataFrame({
'A': ['a1', 'a1', 'a2', 'a2', 'a1'],
'B': ['b2', 'b1', 'b2', 'b2', 'b1'],
'C': [1, 2, 3, 4, 5],
})
pd.crosstab(df.A, df.B)
'''
B b1 b2
A
a1 2 1
a2 0 2
'''
# 整体中的占比
pd.crosstab(df.A, df.B, normalize=True)
# 在列中的占比
pd.crosstab(df.A, df.B, normalize='columns')
pd.melt(frame, id_vars=None, value_vars=None, var_name='variable', value_name='value', col_level=None)
)
参数说明
df = pd.DataFrame({
'A': ['a1', 'a2', 'a3', 'a4', 'a5'],
'B': ['b1', 'b2', 'b3', 'b4', 'b5'],
'C': [1, 2, 3, 4, 5]
})
df.melt()
'''
variable value
0 A a1
1 A a2
2 A a3
3 A a4
4 A a5
5 B b1
6 B b2
7 B b3
8 B b4
9 B b5
10 C 1
11 C 2
12 C 3
13 C 4
14 C 5
'''
df.melt(id_vars=['A'], value_vars=['B'], var_name='Blabel', value_name='B_value')
虚拟变量(Dummy Variable)又称虚设变量, 名义变量或哑变量, 是一个用来反映质的属性的人工变量, 是量化了的自变量, 通常取值为0或1, 常被用于one-hot特征提取
pd.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
df = pd.DataFrame({
'a': list('abcd'),
'b': list('fehg'),
'a1': range(4),
'b1': range(4, 8)})
# 对a进行one-hot操作
pd.get_dummies(df.a)
'''
a b c d
0 1 0 0 0
1 0 1 0 0
2 0 0 1 0
3 0 0 0 1
'''
# 保持其他列的情况下, 对a进行one-hot
pd.get_dummies(df, columns=['a']) # 只对a进行one-hot处理
'''
b a1 b1 a_a a_b a_c a_d
0 f 0 4 1 0 0 0
1 e 1 5 0 1 0 0
2 h 2 6 0 0 1 0
3 g 3 7 0 0 0 1
'''
因子化是指讲一个存在大量重复值的一维数据解析成枚举值的过程, 这样可以方便我们进行分辨. factorize既可以用作顶层函数pd.factorize(), 也可以用作Series.factorize()和Index.factorize()方法
对数据因子化后返回两个值, 一个是因子化后的编码列表, 另一个是原数据的去重值列表
data = ['b', 'b', 'a', 'c', 'b']
pd.factorize(data) # 返回编码, 和去重置
'''
(array([0, 0, 1, 2, 0], dtype=int64), array(['b', 'a', 'c'], dtype=object))
'''
#
cat = pd.Series(['a', 'a', 'c'])
codes, uniques = pd.factorize(cat)
codes, uniques
'''
(array([0, 0, 1], dtype=int64), Index(['a', 'c'], dtype='object'))
'''
codes, uniques = pd.factorize(['b', 'b', 'a', 'c', 'b'], sort=True)
codes, uniques
'''
(array([1, 1, 0, 2, 1], dtype=int64), array(['a', 'b', 'c'], dtype=object))
'''
# 缺失值不会出现在唯一值列表中, 在编码中将为-1
codes, uniques = pd.factorize(['b', None, 'a', 'c', 'b'], sort=True)
codes, uniques
'''
(array([ 1, -1, 0, 2, 1], dtype=int64),
array(['a', 'b', 'c'], dtype=object))
'''
Pandas的枚举类型数据Categorical也可以使用此方法
因子化方法pd.factorize()做了两件事, 一是对数据进行数字编码, 二是对数据进行去重, 在大序列数据中, 因子化能帮助我们抽取数据特征, 将数据变成类别数据再进行分析.
将类似列表每个元素转换为一行, 索引值是相同的
s = pd.Series([[1, 2, 3], 'foo', [], [3, 4]])
s.explode()
'''
0 1
0 2
0 3
1 foo
2 NaN
3 3
3 4
dtype: object
'''
# 每行列表中的元素都独占了一行, 而索引保持不变, 空列表变成了NaN
df = pd.DataFrame({'A': [[1, 2, 3], 'foo', [], [3, 4]], 'B': range(4)})
df.explode('A')
'''
A B
0 1 0
0 2 0
0 3 0
1 foo 1
2 NaN 2
3 3 3
3 4 3
'''
df = pd.DataFrame([{'var1': 'a, b, c', 'var2': 1}, {'var1': 'd, e, f', 'var2': 2}])
'''
var1 var2
0 a, b, c 1
1 d, e, f 2
'''
df.assign(var1=df.var1.str.split(',')).explode('var1')
'''
var1 var2
0 a 1
0 b 1
0 c 1
1 d 2
1 e 2
1 f 2
'''