Python notes 2 - pandas 部分

接下来进行pandas module部分的学习,和主要用于处理array和matrix的numpy module不同,pandas则主要处理series和dataframe类型的数据。
更具体地说,有以下几个数据类别:
1 series:one dimension,与numpy中的一维array以及基本python数据类型的list很像。区别是:list中的元素可以是不同的数据类型,array中的数据类型主要是numeric,series中的元素可以是不同的数据类型,并且有相应的索引。
2 time series:相应的,当索引为时间格式时,就生成了time series数据类型。
3 dataframe:表格型数据结构。很多功能与R中的data.frame类似。可以将dataframe理解为series的容器。dataframe比series用的更为频繁些,也有相应的索引。
4 panel :三维的数组,可以理解为dataframe的容器。用的比较少。

所以接下来从series和dataframe两个部分来学习pandas module。

SERIES

1 Series的创建

1 pd.Series(list,index=[ ]),
第一个参数可以是list或者array,同样也可以是dict(key作为索引),也可以是dataframe的某一行或者某一列。
第二个参数是Series中数据的索引,可以省略。

import numpy as np
import pandas as pd
print(pd.Series([1,4,'ww','tt'])) # 第一个参数为list
print(pd.Series(np.arange(10))) # 第一个参数为array
print(pd.Series(['leo','man',26],index=['name','sex','age'])) # 自己创建索引
print(pd.Series({'python':9000,'c++':9001,'c#':9000})) # 第一个参数为dictionary
a=pd.Series([1,4,'ww','tt'])
print(a.index)
print(a.values)

2 Series索引的应用

import pandas as pd
import numpy as np
### 根据索引查看值和修改值
a=pd.Series([1,4,'ww','tt'])
print(a[0])
a[0]="leo"
print(a)
### 对于dictionary来说,如果自定义了索引,自定的索引会自动寻找原来的索引,如果一样的,就取原来索引对应的值,如果没有值,都对齐赋给NaN。
b={'python':9000,'c++':9001,'c#':9000}; c=pd.Series(b,index=['java','c++','c#'])
print(c)
### output:
### java    NaN
### c++    9001.0
### c#    9000.0
### dtype: float64
######--------------------------------------------------------------------------------
### 索引的名字是可以从新定义
c.index= ['语文','数学','English']
print(c)
### output:
### 语文    NaN
### 数学   9001.0
### English    9000.0
### dtype: float64

3 Series的直方统计

pd.value_counts()
和DataFrame结合起来使用感觉特别好

import numpy as np
import pandas as pd
example=pd.Series(np.random.randint(0, 5, size=10)) ### 生成范围在[0,5]的随机int整数序列
example.value_counts() ### 对上面序列完成直方统计

4 Series的字符串处理

import numpy as np
import pandas as pd
example=pd.Series(['A','B','C','Aab','Baca',np.nan,np.nan,'CABA','dog','cat'])
example.str.lower() ### 对字符串进行全部小写处理

5 Series的shift()函数

import numpy as np
import pandas as pd
example=pd.Series([1,2,3,np.nan,4,5]).shift(2)
### 注意shift()的作用,shift(2)说明行往下移两个单位
### output:
### 0    NaN
### 1    NaN
### 2    1.0
### 3    2.0
### 4    3.0
### 5    NaN
### dtype: float64

6 Series的cut()和qcut()函数

cut() 函数(以值为依据实现分箱)及 qcut() 函数(以样本分位数为依据实现分箱)用于连续值的离散化,常用于连续变量的分箱操作。

import pandas as pd
factor1 = pd.cut(arr, [-5, -1, 0, 1, 5])
factor2 = pd.qcut(arr, [0, .25, .5, .75, 1])
### 定义分箱时,还可以传递无穷值。
factor3 = pd.cut(arr, [-np.inf, 0, np.inf])

10 杂七杂八的Series笔记总结

1 NumPy的mean、std、sum 等方法默认不统计 Series 里的空值。
2 Series.nunique() 返回 Series 里所有非空值的唯一值。
3 Series.astype(‘category’),将Series属性变为“category”类别

DataFrame

1 DataFrame的生成

大概来说,常用的有:1 直接生成;2 通过dictionary生成。

import numpy as np
import pandas as pd
### 直接生成
dates = pd.date_range('20200101', periods=6)
example = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(example)
### output:
###                    A         B         C         D
### 2020-01-01  0.469112 -0.282863 -1.509059 -1.135632
### 2020-01-02  1.212112 -0.173215  0.119209 -1.044236
### 2020-01-03 -0.861849 -2.104569 -0.494929  1.071804
### 2020-01-04  0.721555 -0.706771 -1.039575  0.271860
### 2020-01-05 -0.424972  0.567020  0.276232 -1.087401
### 2020-01-06 -0.673690  0.113648 -1.478427  0.524988

### 通过dictionary生成
example = pd.DataFrame({'A': 1.,'B': pd.Timestamp('20200102'),'C': pd.Series(1, index=list(range(4)), dtype='float32'),'D': np.array([3] * 4, dtype='int32')})
print(example)
### output:
###      A          B    C  D      
### 0  1.0 2020-01-01  1.0  3
### 1  1.0 2020-01-01  1.0  3
### 2  1.0 2020-01-01  1.0  3
### 3  1.0 2020-01-01  1.0  3

2 DataFrame性质展示常用函数

1 example.dtypes:查看每列的数据类型
2 example.head():默认查看前五行
3 example.tail():默认查看后五行
4 example.index:查看索引
5 example.columns:查看列名
6 example.describe():可以快速查看数据的统计摘要
7 example.T:实现DataFrame的转置
8 example.sort_index(axis=1, ascending=False):按列名进行排序
9 example.sort_values(by=“A”):按列值进行排序,如例子按A列的值进行排序
10 example.T:

3 DataFrame与Array的相互转换

NumPy 数组只有一种数据类型,DataFrame 每列的数据类型可以各不相同。当DataFrame每列的数据类型一样时,使用to_numpy()可以实现较快转换,当DataFrame 每列的数据类型各不相同时,使用to_numpy() 就会耗费较多资源。

import numpy as np
import pandas as pd
dates = pd.date_range('20200101', periods=6)
example = pd.DataFrame(np.random.randn(6, 4), index=dates, columns=list('ABCD'))
print(example.to_numpy())
### output:
### array([[ 0.4691, -0.2829, -1.5091, -1.1356],
###        [ 1.2121, -0.1732,  0.1192, -1.0442],
###        [-0.8618, -2.1046, -0.4949,  1.0718],
###        [ 0.7216, -0.7068, -1.0396,  0.2719],
###        [-0.425 ,  0.567 ,  0.2762, -1.0874],
###        [-0.6737,  0.1136, -1.4784,  0.525 ]])

4 DataFrame的索引和数据选择

1 选择特定列:example.A or example[“A”]
2 选择特定行:example[0:3]
3 按条件筛选:example.loc[‘20200102’:‘20200104’, [‘A’, ‘B’]] (index and column names) or example.loc[:, [‘A’, ‘B’]]
4 快速访问标量:example.at[dates[0], ‘A’]
5 按特定位置筛选:example.iloc[3:5, 0:2] 行列 or example.iloc[3] 行 or df.iloc[[1, 2, 4], [0, 2]]
6 快速访问标量:example.iat[1, 1]
7 布尔索引:example[example.A > 0] 等价于 example。wher(example.A > 0);where使用可选other参数替换条件为False的值:example.where(example < 0, -example);另外,where有一个可选参数,inplace以便可以在不创建副本的情况下修改原始数据:example.where(example > 0, -example, inplace=True)。
8 isin()索引:example[example[‘E’].isin([‘two’, ‘four’])]
9 重建索引:example.reindex(index=dates[0:4], columns=list(example.columns) + [‘E’]) [reindex() 可以更改、添加、删除指定轴的索引,并返回数据副本,原数据不会被更改。]
10 索引排序:example.sort_index(),注意如果按index来进行筛选,筛选条件中有index不存在于Series或者DataFrame中,如果index是乱序的且未经过排序,输出结果会报错的。
11 .loc,.iloc以及[]索引也可以接受一个callable索引器。在callable必须与一个参数(调用系列或数据帧)返回的有效输出索引功能。example.loc[lambda df: df.A > 0, :] or example.loc[:, lambda df: [‘A’, ‘B’]]。
12 不推荐使用IX索引器。.loc,如果是想标记索引;.iloc,如果是想要定位索引。

13 选择随机样本,这个对于建模随机选择训练集和测试集特别有用,sample()方法随机选择Series或DataFrame中的行或列。
13.1 默认情况下,该方法将对行进行采样,并接受要返回的特定行数/列数或一小部分行。example.sample(n=3) or example.sample(frac=0.5)。
13.2 默认情况下,sample最多会返回每行一次,但也可以使用以下replace选项进行替换:s.sample(n=6, replace=False) or s.sample(n=6, replace=True)则会返回重复行。
13.3 非等权重取样,默认情况下,每行具有相同的选择概率,但如果希望每行具有不同的概率,则可以在sample()中加入权重参数weights。这些权重可以是list,array或series,但它们的长度必须与采样的对象的长度相同。缺失的值将被视为零的权重,并且不允许使用inf值。如果权重不总和为1,则通过将所有权重除以权重之和来进行重新赋予新的权重。

import pandas as pd
import numpy as np
example = pd.Series([0, 2, 4, 6, 8, 10])
example_weights = [0, 0, 0.2, 0.2, 0.2, 0.4]
example.sample(n=3, weights=example_weights)
### or
example.sample(n=3, weights=[0, 0, 0.2, 0.2, 0.2, 0.4])

example = pd.DataFrame({'col1': [9, 8, 7, 6],\
                        'weight_column': [0.5, 0.4, 0.1, 0]})
example.sample(n=3, weights='weight_column')

13.4 sample()还允许用户使用axis=0或者axis=1参数进行选择对列或是行进行采样。
13.5 sample()使用random_state参数为随机数生成器设置种子,该参数将接受整数(作为种子)或NumPy RandomState对象。sample(n=2, random_state=2)

14 query():DataFrame对象有一个query()允许使用表达式进行选择的方法。这个方法可以获取列的值,其中列b具有列值a和值之间的值c。example.query(’(a < b) & (b < c)’);另外,query()支持 Python的"in"和"not in"的比较运算符的特殊用法:df.query(‘a in b’)
15 duplicated()和drop_duplicates()。每个都将用于标识重复行的列作为参数。duplicated 返回一个布尔向量,其长度为行数,表示行是否重复;drop_duplicates 删除重复的行。

### keep参数设置:
### keep='first' (默认值):标记/删除重复项,第一次出现除外。
### keep='last':标记/删除重复项,除了最后一次出现。
### keep=False:标记/删除所有重复项。

import numpy as np; import pandas as pd
example = pd.DataFrame({'a': ['one', 'one', 'two', 'two', 'two', 'three', 'four'],\
                        'b': ['x', 'y', 'x', 'y', 'x', 'x', 'x'],\
                        'c': np.random.randn(7)})
example.duplicated('a'); 
### output:
### 0    False
### 1     True
### 2    False
### 3     True
### 4     True
### 5    False
### 6    False
### dtype: bool 
example.duplicated('a', keep='last')
### output:
### 0     True
### 1    False
### 2     True
### 3     True
### 4    False
### 5    False
### 6    False
### dtype: bool

example.drop_duplicates('a')
example.drop_duplicates('a', keep='last')
example.drop_duplicates('a', keep=False)
example.drop_duplicates(['a', 'b'])

16 lookup():在给定一系列行标签和列标签的情况下提取一组值,并且该lookup方法允许此操作并返回NumPy数组。
example = pd.DataFrame(np.random.rand(20, 4), columns = [‘A’, ‘B’, ‘C’, ‘D’]).
lookup(list(range(0, 10, 2)), [‘B’, ‘C’, ‘A’, ‘B’, ‘D’])
return:“array([0.6052, 0.6905, 0.1032, 0.9860, 0.1982])”

5 DataFrame的赋值

1 example[“F”]=pd.Series([1, 2, 3, 4, 5, 6], index=pd.date_range(‘20200101’, periods=6))
2 按标签赋值:example.at[dates[0], ‘A’] = 0
3 按位置赋值:example.iat[0, 1] = 0
4 按 NumPy 数组赋值:example.loc[:, ‘D’] = np.array([5] * len(df))
5 用 where 条件赋值:example[example > 0] = 0

6 DataFrame的缺失值处理

6.1 Nan相关

Pandas 主要用 np.nan 表示缺失数据。 计算时,默认不包含空值。
1 example.dropna(how=“any”):删除所有含缺失值的行
2 example.fillna(value=“aa”):填充缺失值,括号当中为填充的数值
3 pd.isna(example):提取 nan 值的布尔值,true or false
4 np.nan
5 example.notna():提取 nan 值的布尔值,true(not nan) or false(nan)
6 注意:pandas/NumPy uses the fact that “np.nan != np.nan”
7 example.fillna(method=‘pad’, limit=1):
Method: pad / ffill, which is “Fill values forward”; bfill / backfill, which is “Fill values backward”.
8 example.fillna(example.mean()):均值填充null value;example.fillna(example.mean()[‘B’:‘C’]):仅B C列。

6.2 interpolate()

1 example.interpolate():插值法填充null value;"method"参数,option: “time”, “values”
“values”: For a floating-point index
“quadratic”: dealing with a time series that is growing at an increasing rate
“pchip”: have values approximating a cumulative distribution function
“akima”: fill missing values with goal of smooth plotting
in addition, “‘spline’, order=2”, “cubic”, “‘polynomial’, order=2”, “linear”.

2 example.interpolate(limit=1, limit_direction=‘backward’ or ‘both’)

6.3 replace()

可以用replace()来完成 null value的替换。
1 example.replace(0, 5)
2 example.replace([0, 1, 2, 3, 4], [4, 3, 2, 1, 0])
3 specify a mapping dict:example.replace({0: 10, 1: 100})
4 specify individual values by column:example.replace({‘a’: 0, ‘b’: 5}, 100)
5 example.replace([1, 2, 3], method=‘pad’ or ‘backfill’)
6 example.replace([r’.’, r’(a)’], [‘dot’, r’\1stuff’], regex=True)
7 example.replace(r’\s*.\s*’, np.nan, regex=True)

7 DataFrame的统计函数

7.1 mean()

1 example.mean():按列求均值
2 example.mean(1):按行求均值

7.2 其他常用的描述性统计函数

Series 与 DataFrame 支持大量计算描述性统计的方法与操作。这些方法大部分都是 sum()、mean()、quantile() 、std()等聚合函数,其输出结果比原始数据集小;此外,还有输出结果与原始数据集同样大小的 cumsum() 、 累乘cumprod()、累积最大值cummax()、累积最小值cummin() 等函数。这些方法都基本上都接受 axis 参数。kurt(),skew(),var(),median(),min(),max(),count(),

8 DataFrame的合并处理

8.1 concat()函数

pd.concat(objs, axis=0, join=‘outer’ or ‘inner’, ignore_index=False, keys=None,
levels=None, names=None, verify_integrity=False, copy=True)

import pandas as pd
pd.concat([df[:3], df[3:7], df[7:]]) ### 逐行逐行进行合并

### application of "keys" parameter
example2 = pd.concat(example, keys=['x', 'y', 'z'])
example2.loc['y']
result = pd.concat([df1, df4], axis=1, sort=False)

8.2 append()函数

### some example about append()
example = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
raw_1 = example.iloc[3]
example.append(raw_1, ignore_index=True) 
### default "axis=0", 在DataFrame的最后一行后新增一行,并且忽略index

result = example.append(example, sort=False) ### 不排序
result = example1.append([example1, example2]) 
### append all the example, example1, example2

result = pd.concat([exmaple, example1], ignore_index=True, sort=False)
### ignore the index

result = pd.concat([example, s1], axis=1, ignore_index=True)
### notice that "axis=1" and ignore index would lead to
### "drop all name references(columns names)"

result = pd.concat([example,example1,example2], keys=['x', 'y', 'z'])
### which is similar to the function of "keys" in "concat"

pieces = {'x': df1, 'y': df2, 'z': df3}
result = pd.concat(pieces)
result = pd.concat(pieces, keys=['z', 'y'])
### combine the "dictionary" and "keys" in "concat"

8.3 join() 函数

import pandas as pd
import numpy as np

result = left.join(right) ### default: left inner join
result = left.join(right, how='outer')
result = left.join(right, how='inner')

result = left.join(right, on='key')
### "on='key'" means that the join key comes from the "key" column of the left table;
### it would search the key words from the right table to combine these 2 tables.

### Joining on multiple keys
result = left.join(right, on=['key1', 'key2'])

### join() has lsuffix and rsuffix arguments
left = left.set_index('k'); right = right.set_index('k')
result = left.join(right, lsuffix='_l', rsuffix='_r')

### Joining multiple DataFrames
result = left.join([right, right2])

8.4 merge()函数

类似于SQL 风格的表格合并。感觉类似于SQL的inner join
pd.merge(left, right, how=‘inner’, on=None, left_on=None, right_on=None,
left_index=False, right_index=False, sort=True,
suffixes=(’_x’, ‘_y’), copy=True, indicator=False,
validate=None)
解释:
1 how: ‘left’, ‘right’, ‘outer’, ‘inner’. Defaults to “inner”
2 validate: string, default None. If specified, checks if merge is of specified type.
“one_to_one” or “1:1”: checks if merge keys are unique in both left and right datasets.
“one_to_many” or “1:m”: checks if merge keys are unique in left dataset.
“many_to_one” or “m:1”: checks if merge keys are unique in right dataset.
“many_to_many” or “m:m”: allowed, but does not result in checks.
3 indicator: If True, a Categorical-type column called _merge will be added to the output object that takes on values.(类似于SAS “merge” 中的 “in” 含义)
left_only; right_only; both

import pandas as pd
left = pd.DataFrame({'key': ['aa', 'aa'], 'left': [1, 2]})
right = pd.DataFrame({'key': ['aa', 'aa'], 'right': [1.1, 2.2]})
print(left)
### output:
###    key  left
### 0   aa     1
### 1   aa     2
print(right)
### output:
###    key right
### 0   aa   1.1
### 1   aa   2.2
pd.merge(left, right, on='key')
### output:
###    key  left right
### 0   aa     1   1.1
### 1   aa     1   2.2
### 2   aa     2   1.1
### 3   aa     2   2.2

### the example of "category' and "merge"
from pandas.api.types import CategoricalDtype
import pandas as pd
import numpy as np

X = pd.Series(np.random.choice(['foo', 'bar'], size=(10,)))
X1 = X.astype(CategoricalDtype(categories=['foo', 'bar']))
left = pd.DataFrame({'X': X1,\
                     'Y': np.random.choice(['one', 'two', 'three'],\
                                           size=(10,))})
left.dtypes
### output:
### X    category
### Y      object
### dtype: object

### Joining on index
result = pd.merge(left, right, left_index=True, right_index=True, how='outer')
result = pd.merge(left, right, left_index=True, right_index=True, how='inner')

result = left.join(right, on='key')
### or
result = pd.merge(left, right, left_on='key', right_index=True,\
                  how='left', sort=False)
### the above equations would get the same results

### the application of "suffixes"
result = pd.merge(left, right, on='k', suffixes=['_l', '_r'])

8.5 combine_first()函数

如果我们要合并两个相似的数据集,两个数据集里的其中一个的数据比另一个多。即其中一个是“高质量”指标,另一个是“低质量”指标。一般来说,低质量序列可能包含更多的历史数据,或覆盖更广的数据。因此,要合并这两个 DataFrame 对象,其中一个 DataFrame 中的缺失值将按指定条件用另一个DataFrame 里类似标签中的数据进行填充。要实现这一操作便可以使用combine_first()函数。

import pandas as pd
example1.combine_first(example2)

8.6 MultiIndexes

leftindex = pd.MultiIndex.from_product([list('abc'), list('xy'), [1, 2]],\
                                        names=['abc', 'xy', 'num'])
left = pd.DataFrame({'v1': range(12)}, index=leftindex)
rightindex = pd.MultiIndex.from_product([list('abc'), list('xy')],\
                                        names=['abc', 'xy'])
right = pd.DataFrame({'v2': [100 * i for i in range(1, 7)]}, index=rightindex)
left.join(right, on=['abc', 'xy'], how='inner')

8.7 ???merge_ordered()

A merge_ordered()function allows combining time series and other ordered data. In particular it has an optional fill_method keyword to fill/interpolate missing data.
result=DataFrame.merge_ordered(left, right, on=None, left_on=None, right_on=None, left_by=None, right_by=None,fill_method=None, suffixes=’_x’, ‘_y’, how: str = ‘outer’)

left = pd.DataFrame({'k': ['K0', 'K1', 'K1', 'K2'],\
                     'lv': [1, 2, 3, 4],\
                     's': ['a', 'b', 'c', 'd']})
In [131]: right = pd.DataFrame({'k': ['K1', 'K2', 'K4'],\
                                'rv': [1, 2, 3]})
pd.merge_ordered(left, right, fill_method='ffill', left_by='s')
### ?the final result would order by the key column "s" and combine by the key column "k"

9 Groupby()分组函数

分组函数一般和size计数和sum求和等常用计算函数结合起来一起使用

import numpy as np
import pandas as pd
example.groupby('A').sum() ### 先分组,再用 sum()函数计算每组的汇总数据
example.groupby(['A', 'B']).sum() ### 多列分组后,生成多层索引,也可以应用 sum 函数
example.groupby(['X'], sort=False).sum() ### 同时也可以用sort参数完成排序操作
example.groupby('X').get_group('A')
example.groupby('X', axis=1).groups ### 利用groups生成dictionary

10 DataFrame的堆砌Stack

tuples = list(zip(*[['bar', 'bar', 'baz', 'baz','foo', 'foo', 'qux', 'qux'], ['one', 'two', 'one', 'two','one', 'two', 'one', 'two']]))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
example = pd.DataFrame(np.random.randn(8, 2), index=index, columns=['A', 'B'])
example2 = example[:4]
print(example2)
### output:
###                      A         B
### first second                    
### bar   one     0.029399 -0.542108
###       two     0.282696 -0.087302
### baz   one    -1.575170  1.771208
###       two     0.816482  1.100230

### stack()方法把DataFrame列压缩至一层
stacked = example2.stack()
print(stacked)
### output:
### first  second   
###                B   -0.542108
###        two     A    0.282696
###                B   -0.087302
### baz    one     A   -1.575170
###                B    1.771208
###        two     A    0.816482
###                B    1.100230
### dtype: float64
### 压缩后的DataFrame或Series具有多层索引

### stack()的逆操作是unstack(),默认为拆叠最后一层
print(stacked.unstack())
print(stacked.unstack(1))
print(stacked.unstack(0))
### output:
###                      A         B
### first second                    
### bar   one     0.029399 -0.542108
###       two     0.282696 -0.087302
### baz   one    -1.575170  1.771208
###       two     0.816482  1.100230

### second        one       two
### first                      
### bar   A  0.029399  0.282696
###       B -0.542108 -0.087302
### baz   A -1.575170  0.816482
###       B  1.771208  1.100230

### first          bar       baz
### second                      
### one    A  0.029399 -1.575170
###        B -0.542108  1.771208
### two    A  0.282696  0.816482
###        B -0.087302  1.100230

11 DataFrame的数据透视表

example = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 3,'B': ['A', 'B', 'C'] * 4,'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,'D': np.random.randn(12), 'E': np.random.randn(12)})
### 用pivot_table()生成数据透视表
print(pd.pivot_table(example, values='D', index=['A', 'B'], columns=['C']))
### output:
### C             bar       foo
### A     B                    
### one   A -0.773723  1.418757
###       B -0.029716 -1.879024
###       C -1.146178  0.314665
### three A  1.006160       NaN
###       B       NaN -1.035018
###       C  0.648740       NaN
### two   A       NaN  0.100900
###       B -1.170653       NaN
###       C       NaN  0.536826

12 DataFrame的分类处理

12.1 category处理

对于处理标签类型变量时使用,如逻辑回归,Classification Methods

### 生成DataFrame
example = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6],"raw_grade": ['a', 'b', 'b', 'a', 'a', 'e']})
print(example)

### 将grade的原始数据转换为类别型数据
example["grade"] = example["raw_grade"].astype("category")
print(example["grade"])
### ouytput:
### 0    a
### 1    b
### 2    b
### 3    a
### 4    a
### 5    e
### Name: grade, dtype: category
### Categories (3, object): [a, b, e]

### 用有含义的名字重命名不同类型,调用 Series.cat.categories。
example["grade"] = example["raw_grade"].cat.categories = ["very good", "good", "very bad"]
### 重新排序各类别,并添加缺失类,Series.cat 的方法默认返回新 Series。
example["grade"] = example["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
print(example["grade"])
### output:
### 0    very good
### 1         good
### 2         good
### 3    very good
### 4    very good
### 5     very bad
### Name: grade, dtype: category
### Categories (5, object): [very bad, bad, medium, good, very good]

### 注意,这里是按生成类别时的顺序排序,不是按词汇排序
df.sort_values(by="grade")
### output:
###    id raw_grade      grade
### 5   6         e   very bad
### 1   2         b       good
### 2   3         b       good
### 0   1         a  very good
### 3   4         a  very good
### 4   5         a  very good

### 按类列分组(groupby)时,即便某类别("medium", "bad")为空,也会显示。
df.groupby("grade").size()
### output:
### grade
### very bad     1
### bad          0
### medium       0
### good         2
### very good    3
### dtype: int64

### 根据观察,先需要调用cat.categories()使类型标签一一对应(a-"very good", b-"good", e-"very bad"), 之后继续调用cat.set_categories()可以使标签类型变量更加完整,没有的变量被添加缺失值。

### 生成DataFrame时,直接将变量定义为category类型
example=pd.DataFrame({'A': list('abca'), 'B': list('bccd')}, dtype="category")
example.dtypes
### output:
### A    category
### B    category
### dtype: object

from pandas.api.types import CategoricalDtype
s = pd.Series(["a", "b", "c", "a"])
cat_type = CategoricalDtype(categories=["b", "c", "d"],ordered=True)
s_cat = s.astype(cat_type)
print(s_cat)
### output:
### 0    NaN
### 1      b
### 2      c
### 3    NaN
### dtype: category
### Categories (3, object): [b < c < d]

12.2 cut()

cut的功能主要是给numeric类型变量划分一系列区间,为之后的category处理做准备。

import numpy as np
import pandas as pd

np.random.seed(666)
### 指定多个区间
bins = [0, 20, 40, 60, 80, 100]
series = np.random.randint(0, 100, size=50)
cut = pd.cut(series, bins)

print(pd.value_counts(cut)) ### 统计每个区间人数

之后,还可以继续了解更多关于category的处理以及pandas.qcut()的处理。

13 DataFrame的比较操作

1 eq equal to 等于
2 ne not equal to 不等于
3 lt less than 小于
4 gt greater than 大于
5 le less than or equal to 小于等于
6 ge greater than or equal to 大于等于

example.gt(example2) ### 比较example和example2是否相等
### output:
###      one    two  three
### a  False  False  False
### b  False  False  False
### c  False  False  False
### d  False  False  False

13.1 布尔简化

empty、any()、all()、bool() 可以把数据汇总简化至单个布尔值。

### all()代表前面式子均要成立才返回“true”
(example > 0).all()
### output:
### one      False
### two       True
### three    False
### dtype: bool
### any()代表前面式子只要满足一个就返回“true”
(example > 0).any()
### output:
### one      True
### two      True
### three    True
### dtype: bool

### 进一步把上面的结果简化为单个布尔值
(example > 0).any().any()
### output:
### True

### 通过 empty 属性,可以验证Pandas对象是否为空。
example.empty
### output: False
pd.DataFrame(columns=list('aaa')).empty
### output: True

### 用bool()方法验证单元素pandas对象的布尔值。
pd.Series([True]).bool()
### output: True

13.2 有关列表间的nan值比较

### 使用下面等式,两个NaN值的比较结果为不等
example + example == example * 2
### output:
###      one   two  three
### a   True  True  False
### b   True  True   True
### c   True  True   True
### d  False  True   True

### 使用equals()方法,用这个方法验证NaN值的结果为相等。
(example + example).equals(example * 2)
### output:
### True

13.3 其他相关问题

Series 与 DataFrame 索引的顺序必须一致,验证结果才能为 True;
Pandas 还能对比两个等长 array 对象里的数据元素,但注意需要等长;

14 DataFrame的函数应用

14.1 pipe()

表级函数应用:
(df.pipe(h)
… .pipe(g, arg1=1)
… .pipe(f, arg2=2, arg3=3))
解释:上述表达式为链式方法。在链式方法中调用自定义函数或第三方支持库函数时,用 pipe 更容易,与用 Pandas 自身方法一样。上例中,f、g 与 h 这几个函数都把 DataFrame 当作首位参数。要是想把数据作为第二个参数,.pipe 把 DataFrame 作为元组里指定的参数,即pipe(function,‘data’)。

(bb.query('h > 0')
	.assign(ln_h=lambda df: np.log(df.h))
	.pipe((sm.ols, 'data'), 'hr ~ ln_h + year + g + C(lg)')
	.fit()
	.summary()
)

14.2 apply()

行列级函数应用:
使用apply(),可以实现将括号中的函数对DataFrame的每一列或每一行进行类似list的处理,apply(function)对列进行处理;apply(function,axis=1)则是对行进行处理。

import numpy as np
import pandas as pd
example.apply(np.cumsum)
### output:
###                    A         B         C   D     F
### 2013-01-01  0.000000  0.000000 -1.509059   5   NaN
### 2013-01-02  1.212112 -0.173215 -1.389850  10   1.0
### 2013-01-03  0.350263 -2.277784 -1.884779  15   3.0
### 2013-01-04  1.071818 -2.984555 -2.924354  20   6.0
### 2013-01-05  0.646846 -2.417535 -2.648122  25  10.0
### 2013-01-06 -0.026844 -2.303886 -4.126549  30  15.0
example.apply(lambda x: x.max() - x.min())
### output:
### A    2.073961
### B    2.671590
### C    1.785291
### D    0.000000
### F    4.000000
### dtype: float64

### apply() 方法还支持通过函数名字符串调用函数。
example.apply('mean')

14.3 agg()

应用单个函数或者聚合多个函数使用:

### 应用单个函数,类似于apply()函数
example.agg(np.sum)

### 聚合多个函数
print(example.agg(['sum', 'mean']))
### output:
###              A         B         C
### sum   3.033606 -1.803879  1.575510
### mean  0.505601 -0.300647  0.262585
### or
example.A.agg(['sum', lambda x: x.mean()])

### 用字典实现聚合
example.agg({'A': 'mean', 'B': 'sum'})
### output:
### A    0.505601
### B   -1.803879
### dtype: float64
### or
example.agg({'A': ['mean', 'min'], 'B': 'sum'})
### output:
###              A         B
### mean  0.505601       NaN
### min  -0.749892       NaN
### sum        NaN -1.803879

14.4 transform()

该方法的返回结果与原始数据的索引相同,大小相同。与 .agg API 类似。

import pandas as pd
import numpy as np

### transform() 调用多个函数时,生成多层索引 DataFrame。第一层是原始数据集的列名;第二层是 transform() 调用的函数名。
example.transform([np.abs, lambda x: x + 1])
### output:
###                    A                   B                   C          
###             absolute  <lambda>  absolute  <lambda>  absolute  <lambda>
### 2000-01-01  0.428759  0.571241  0.864890  0.135110  0.675341  0.324659
### 2000-01-02  0.168731  0.831269  1.338144  2.338144  1.279321 -0.279321
### 2000-01-03  1.621034 -0.621034  0.438107  1.438107  0.903794  1.903794
### 2000-01-04       NaN       NaN       NaN       NaN       NaN       NaN
### 2000-01-05       NaN       NaN       NaN       NaN       NaN       NaN
### 2000-01-06       NaN       NaN       NaN       NaN       NaN       NaN
### 2000-01-07       NaN       NaN       NaN       NaN       NaN       NaN
### 2000-01-08  0.254374  1.254374  1.240447 -0.240447  0.201052  0.798948
### 2000-01-09  0.157795  0.842205  0.791197  1.791197  1.144209 -0.144209
### 2000-01-10  0.030876  0.969124  0.371900  1.371900  0.061932  1.061932

### transform() 的参数是列表字典时,生成的是以 transform() 调用的函数为名的多层索引 DataFrame。
example.transform({'A': np.abs, 'B': [lambda x: x + 1, 'sqrt']})
###                    A         B          
###             absolute  <lambda>      sqrt
### 2000-01-01  0.428759  0.135110       NaN
### 2000-01-02  0.168731  2.338144  1.156782
### 2000-01-03  1.621034  1.438107  0.661897
### 2000-01-04       NaN       NaN       NaN
### 2000-01-05       NaN       NaN       NaN
### 2000-01-06       NaN       NaN       NaN
### 2000-01-07       NaN       NaN       NaN
### 2000-01-08  0.254374 -0.240447       NaN
### 2000-01-09  0.157795  1.791197  0.889493
### 2000-01-10  0.030876  1.371900  0.609836

14.5 applymap()

元素级函数应用:
并非所有函数都能矢量化,即接受 NumPy 数组,返回另一个数组或值,DataFrame 的 applymap() 及 Series 的 map() ,支持任何接收单个值并返回单个值的 Python 函数。

def f(x):
     return len(str(x))
example['one'].map(f)
example.applymap(f)

### Series.map() 还有个功能,可以“连接”或“映射”第二个 Series 定义的值。
### 这个功能与 merging/joining 功能联系非常紧密。
example= pd.Series(['six', 'seven', 'six', 'seven', 'six'],\
                   index=['a', 'b', 'c', 'd', 'e'])
example1 = pd.Series({'six': 6., 'seven': 7.}) 
example.map(example1) 
### output:
### a    6.0
### b    7.0
### c    6.0
### d    7.0
### e    6.0
### dtype: float64              

15 字符串处理

1 s.str.lower(), s.str.upper(), 大小写转换
2 idx.str.strip(),idx.str.lstrip(),idx.str.rstrip(),去空格
3 清理开头和结尾的白空格,将所有的名称都换为小写,并且将其余的空格都替换为下划线:
df.columns.str.strip().str.lower().str.replace(’ ‘, ‘’)
4 拆分字符串: s2.str.split(’
’, expand=True); 限制切分的次数:s2.str.split(’_’, expand=True, n=1)
5 rsplit与split相似,不同的是,这个切分的方向是反的。即,从字串的尾端向首段切分。
6 拼接序列或者数据表:example.str.cat(example1);s.str.cat(v, join=‘left’, na_rep=’-’)
7 将一个序列与多个对象拼接为一个新的序列:s.str.cat([u, u.to_numpy()], join=‘left’)

16 常用计算工具

1 cov(): example[‘a’].cov(example1[‘a’]),用来计算两列之间的协方差,直接对DataFrame使用cov()的话会得到一个协方差矩阵。
2 corr(): example[‘a’].corr(example[‘b’]),用来计算两列之间的相关系数,直接对DataFrame使用corr()的话会得到一个相关系数矩阵。
3 corrwith(): 对不同的两个DataFrame的有相同名字的列或者index求correlation,example1.corrwith(example2),example1.corrwith(exampl2, axis=1)

4 rolling() and expanding():
window: size of moving window
min_periods: threshold of non-null data points to require (otherwise result is NA)
center: boolean, whether to set the labels at the center (default is False)

import pandas as pd
import numpy as np

example1 = example['b'].rolling(window=60)
example1.mean()

example = pd.DataFrame(np.random.randn(1000, 4),\
                   index=pd.date_range('1/1/2000', periods=1000),\
                   columns=['A', 'B', 'C', 'D'])
example1 = example.cumsum()df.rolling(window=60).sum().plot(subplots=True)
example1.rolling(window=60).sum().plot(subplots=True)

18 Plot()

example.plot(style=‘k–’)
example.mean().plot(style=‘k’)

利用pandas module完成数据导入输出

1 CSV文件导入及输出

import numpy as np
import pandas as pd
### 写入文件
example.to_csv('C:\\Users\\Leoxs\\Desktop\\example.csv')
### 导入文件
example=pd.read_csv('C:\\Users\\Leoxs\\Desktop\\example.csv')

2 Excel文件的导入及输出

import numpy as np
import pandas as pd
### 写入文件
example.to_excel('example.xlsx', sheet_name='Sheet1')
### 导入文件
example=pd.read_excel('example.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值