In [24]: s.values
Out[24]: array([100, 'a', {'dic1': 5}], dtype=object)
In [25]: s.index
Out[25]: Index(['id1', 20, 'third'], dtype='object', name='my_idx')
In [26]: s.dtype
Out[26]: dtype('O')
In [27]: s.name
Out[27]: 'my_name'
In [29]: s['third']
Out[29]: {'dic1': 5}
DataFrame
DataFrame 在 Series 的基础上增加了列索引,一个数据框可以由二维的 data 与行列索引来构造:
In [30]: data = [[1, 'a', 1.2], [2, 'b', 2.2], [3, 'c', 3.2]]
In [31]: df = pd.DataFrame(data = data,
....: index = ['row_%d'%i for i in range(3)],
....: columns=['col_0', 'col_1', 'col_2'])
....:
In [32]: df
Out[32]:
col_0 col_1 col_2
row_0 1 a 1.2
row_1 2 b 2.2
row_2 3 c 3.2
但一般而言,更多的时候会采用从列索引名到数据的映射来构造数据框,同时再加上行索引:
In [33]: df = pd.DataFrame(data = {'col_0': [1,2,3], 'col_1':list('abc'),
....: 'col_2': [1.2, 2.2, 3.2]},
....: index = ['row_%d'%i for i in range(3)])
....:
In [34]: df
Out[34]:
col_0 col_1 col_2
row_0 1 a 1.2
row_1 2 b 2.2
row_2 3 c 3.2
由于这种映射关系,在 DataFrame 中可以用 [col_name] 与 [col_list] 来取出相应的列与由多个列组成的表,结果分别为 Series 和 DataFrame
与 Series 类似,在数据框中同样可以取出相应的属性:
In [37]: df.values
Out[37]:
array([[1, 'a', 1.2],
[2, 'b', 2.2],
[3, 'c', 3.2]], dtype=object)
In [38]: df.index
Out[38]: Index(['row_0', 'row_1', 'row_2'], dtype='object')
In [39]: df.columns
Out[39]: Index(['col_0', 'col_1', 'col_2'], dtype='object')
In [40]: df.dtypes # 返回的是值为相应列数据类型的Series
Out[40]:
col_0 int64
col_1 object
col_2 float64
dtype: object
In [41]: df.shape
Out[41]: (3, 3)
转置
In [42]: df.T
Out[42]:
row_0 row_1 row_2
col_0 1 2 3
col_1 a b c
col_2 1.2 2.2 3.2
常用基本函数
特征统计函数
在 Series 和 DataFrame 上定义了许多统计函数,最常见的是 sum, mean, median, var, std, max, min 。
如果想要观察多个列组合的唯一值,可以使用 drop_duplicates 。其中的关键参数是 keep ,默认值 first 表示每个组合保留第一次出现的所在行, last 表示保留最后一次出现的所在行, False 表示把所有重复组合所在的行剔除。
In [60]: df_demo = df[['Gender','Transfer','Name']]
In [61]: df_demo.drop_duplicates(['Gender', 'Transfer'])
Out[61]:
Gender Transfer Name
0 Female N Gaopeng Yang
1 Male N Changqiang You
12 Female NaN Peng You
21 Male NaN Xiaopeng Shen
36 Male Y Xiaojuan Qin
43 Female Y Gaoli Feng
In [62]: df_demo.drop_duplicates(['Gender', 'Transfer'], keep='last')
Out[62]:
Gender Transfer Name
147 Male NaN Juan You
150 Male Y Chengpeng You
169 Female Y Chengquan Qin
194 Female NaN Yanmei Qian
197 Female N Chengqiang Chu
199 Male N Chunpeng Lv
In [63]: df_demo.drop_duplicates(['Name', 'Gender'],
....: keep=False).head() # 保留只出现过一次的性别和姓名组合
....:
Out[63]:
Gender Transfer Name
0 Female N Gaopeng Yang
1 Male N Changqiang You
2 Male N Mei Sun
4 Male N Gaojuan You
5 Female N Xiaoli Qian
In [64]: df['School'].drop_duplicates() # 在Series上也可以使用
Out[64]:
0 Shanghai Jiao Tong University
1 Peking University
3 Fudan University
5 Tsinghua University
Name: School, dtype: object
In [98]: roller.mean()
Out[98]:
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
dtype: float64
In [99]: roller.sum()
Out[99]:
0 NaN
1 NaN
2 6.0
3 9.0
4 12.0
dtype: float64
对于滑动相关系数或滑动协方差的计算,可以如下写出:
In [100]: s2 = pd.Series([1,2,6,16,30])
In [101]: roller.cov(s2)
Out[101]:
0 NaN
1 NaN
2 2.5
3 7.0
4 12.0
dtype: float64
In [102]: roller.corr(s2)
Out[102]:
0 NaN
1 NaN
2 0.944911
3 0.970725
4 0.995402
dtype: float64
此外,还支持使用 apply 传入自定义函数,其传入值是对应窗口的 Series ,例如上述的均值函数可以等效表示:
In [103]: roller.apply(lambda x:x.mean())
Out[103]:
0 NaN
1 NaN
2 2.0
3 3.0
4 4.0
dtype: float64
shift, diff, pct_change 是一组类滑窗函数,它们的公共参数为 periods=n ,默认为1,分别表示取向前第 n 个元素的值、与向前第 n 个元素做差(与 Numpy 中不同,后者表示 n 阶差分)、与向前第 n 个元素相比计算增长率。这里的 n 可以为负,表示反方向的类似操作。
In [104]: s = pd.Series([1,3,6,10,15])
In [105]: s.shift(2)
Out[105]:
0 NaN
1 NaN
2 1.0
3 3.0
4 6.0
dtype: float64
In [106]: s.diff(3)
Out[106]:
0 NaN
1 NaN
2 NaN
3 9.0
4 12.0
dtype: float64
In [107]: s.pct_change()
Out[107]:
0 NaN
1 2.000000
2 1.000000
3 0.666667
4 0.500000
dtype: float64
In [108]: s.shift(-1)
Out[108]:
0 3.0
1 6.0
2 10.0
3 15.0
4 NaN
dtype: float64
In [109]: s.diff(-2)
Out[109]:
0 -5.0
1 -7.0
2 -9.0
3 NaN
4 NaN
dtype: float64
将其视作类滑窗函数的原因是,它们的功能可以用窗口大小为 n+1 的 rolling 方法等价代替:
In [110]: s.rolling(3).apply(lambda x:list(x)[0]) # s.shift(2)
Out[110]:
0 NaN
1 NaN
2 1.0
3 3.0
4 6.0
dtype: float64
In [111]: s.rolling(4).apply(lambda x:list(x)[-1]-list(x)[0]) # s.diff(3)
Out[111]:
0 NaN
1 NaN
2 NaN
3 9.0
4 12.0
dtype: float64
In [112]: def my_pct(x):
.....: L = list(x)
.....: return L[-1]/L[0]-1
.....:
In [113]: s.rolling(2).apply(my_pct) # s.pct_change()
Out[113]:
0 NaN
1 2.000000
2 1.000000
3 0.666667
4 0.500000
dtype: float64