pandas 是一个开源的,BSD许可的库,为Python编程语言提供了高性能,易于使用的数据结构和数据分析工具。
官网:http://pandas.pydata.org/
主要有两个数据结构:Series 、DataFrame
Series 是一种类似于一维数组的对象,它由一组数据以及一组与之相关的数据标签(即索引)组成。
使用list创建Series
# 创建Series
obj = Series([1,2,3,4])
obj.values # 值
obj.index # 索引
使用字典创建Series,字典的键就是Series中的索引
data = {'a':1,'b':2}
obj = Series(data)
obj.index = ['e','f'] # 索引可以通过赋值方式修改
#自定义索引
obj = Series([1,2,3,4],index=['a','b','c','d'])
obj['a'] # 选取单个值
obj[['a','b','c']] # 选取一组值
DataFrame是一个 表格型 的数据结构 它含有一组 有序的列 每列可以是 不同的值类型 数值、字符串、布尔值等 。 Dataframe 既有行索引也有列索引 它可以被看做由 Series 组成的字典 共用同一个索引 。跟其他类似的数据结构相比 如 R 的 dataframe ), Data frame 中 面向行 和 面向列 的操作基本上是平衡的。其实 , Dataframe 中的数据是以一个或多个二维块存放的而不是列表、字典或别的一维数据结构 。
由等长列表或Numpy数组构成的字典来创建DataFrame
data = {'state':['a','b','c'],
'year':[2000,2001,2002],
'pop':[1.2,1.3,1.4]}
frame = DataFrame(data)
#如果指定列序列,则DataFrame的列就会按照指定顺序进行
DataFrame(data,columns=['year','state','pop'])
使用嵌套字典创建DataFrame,外层字典的键作为列,内层键则作为行索引
pop = {'Nevada':{2001:2.4,2002:2.9},
'Ohio':{2000:1.5,2001:1.7,2002:3.6}}
frame = DataFrame(pop)
frame.T # 转置
# 设置index和columns的name
frame.index.name='year'
frame.columns.name='state'
frame.values # 获取值
通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series
frame['state']
frame.state
列可以通过赋值的方式进行修改
frame['in'] = 32
frame['in'] = np.arange(3.)
将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值
var = Series([-1.2,-1.5],index=[0,2])
frame['in'] = var
frame
为不同的列赋值会产生一个新的列,用del关键字删除一列
frame['good']= frame.state == 'b'
del frame['good']
Index
pandas的索引对象负责管理轴标签和其他元数据(比如轴名称)。构建Series或DataFrame时,所用到的任何数组或其他序列的标签都会被转换成一个Index
Index对象是不可修改的(immutable)
obj = Series(range(3),index=['a','b','c'])
index = obj.index
# out:
Index(['a', 'b', 'c'], dtype='object')
index[1]='d' # 不可修改
# out:
TypeError: Index does not support mutable operations
drop
删除索引,即删除该索引对应的行数据。
data = DataFrame(np.arange(16).reshape((4,4)),
index=['Ohio','Colorado','Utah','New York'],
columns=['one','two','three','four'])
data.drop(['Ohio']) # 删除行,drop默认 axis=0为行
data.drop(['one'],axis=1) # 删除列
obj = Series(np.arange(4.),index=['a','b','c','d'])
obj['b']
obj[1]
obj[[1,3]]
obj[obj<2]
obj<2
obj[['b','a']]
利用标签的切片运算与普通的Python切片操作不同,其末端是包含的
obj['b':'c']
# out:
b 1
c 2
# 设置
obj['b':'c'] = 5
#out:
a 0
b 5
c 5
d 3
pandas最重要的一个功能是,它可以对不同索引的对象进行算术运算。在将对象相加时,如果存在不同的索引对,则结果的索引就是该索引对的并集,如果某个索引只在一个对象中存在,在相加的结果为NaN
。
Series
s1 = Series([7.3,-2.5,3.4,1.5],index=['a','c','d','e'])
s2 = Series([-2.1,3.6,-1.5,4,3.1],index=['a','c','e','f','g'])
s1
#out:
a 7.3
c -2.5
d 3.4
e 1.5
dtype: float64
s2
# out:
a -2.1
c 3.6
e -1.5
f 4.0
g 3.1
dtype: float64
s1+s2
# out:
a 5.2
c 1.1
d NaN
e 0.0
f NaN
g NaN
dtype: float64
DataFrame
df1 = DataFrame(np.arange(9.).reshape((3,3)),columns=list('bcd'),index=['Ohio','Texas','Colorado'])
df2 = DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
df1
# out:
b c d
Ohio 0.0 1.0 2.0
Texas 3.0 4.0 5.0
Colorado 6.0 7.0 8.0
df2
# out:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
df1 + df2
# out:
b c d e
Colorado NaN NaN NaN NaN
Ohio 3.0 NaN 6.0 NaN
Oregon NaN NaN NaN NaN
Texas 9.0 NaN 12.0 NaN
Utah NaN NaN NaN NaN
add
在对不同的索引对象进行算术运算时,当一个对象中的某个轴标签在另一个对象中找不到时填充一个特殊值,如果两个对象合并后某个值在两个对象中都不存在时,还是为NaN。
df1.add(df2,fill_value=0)
# out:
b c d e
Colorado 6.0 7.0 8.0 NaN
Ohio 3.0 1.0 6.0 5.0
Oregon 9.0 NaN 10.0 11.0
Texas 9.0 4.0 12.0 8.0
Utah 0.0 NaN 1.0 2.0
DataFrame灵活的算术运算:
方法 | 说明 |
---|---|
add | 用于加法(+)的方法 |
sub | 用于减法(-)的方法 |
div | 用于除法(/)的方法 |
mul | 用于乘法(*)的方法 |
默认情况下DataFrame和Series之间的算术运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播。
frame = DataFrame(np.arange(12.).reshape((4,3)),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
series=frame.iloc[0]
frame
# out:
b d e
Utah 0.0 1.0 2.0
Ohio 3.0 4.0 5.0
Texas 6.0 7.0 8.0
Oregon 9.0 10.0 11.0
series
# out:
b 0.0
d 1.0
e 2.0
Name: Utah, dtype: float64
frame - series
# out:
b d e
Utah 0.0 0.0 0.0
Ohio 3.0 3.0 3.0
Texas 6.0 6.0 6.0
Oregon 9.0 9.0 9.0
apply
frame = DataFrame(np.random.randn(4,3),columns=list('bde'),index=['Utah','Ohio','Texas','Oregon'])
frame
# out:
b d e
Utah -0.431738 -0.083715 -0.557972
Ohio 1.115518 -1.580615 -0.682726
Texas 0.751603 0.123504 0.165463
Oregon 0.405330 -0.718213 -0.096647
np.abs(frame)
# out:
b d e
Utah 0.431738 0.083715 0.557972
Ohio 1.115518 1.580615 0.682726
Texas 0.751603 0.123504 0.165463
Oregon 0.405330 0.718213 0.096647
将函数应用到由各列或行所形成的一维数组上。
f = lambda x: x.max() - x.min()
frame.apply(f)
# out:
b 1.547256
d 1.704119
e 0.848189
dtype: float64
frame.apply(f,axis=1)
# out:
Utah 0.474256
Ohio 2.696133
Texas 0.628099
Oregon 1.123542
dtype: float64
元素级的Python函数也是可以用的,Series 也有一个用于元素级别函数的map方法
format = lambda x: '%.2f' % x
frame.applymap(format)
# out:
b d e
Utah -0.43 -0.08 -0.56
Ohio 1.12 -1.58 -0.68
Texas 0.75 0.12 0.17
Oregon 0.41 -0.72 -0.10
frame['e'].map(format)
# out:
Utah -0.56
Ohio -0.68
Texas 0.17
Oregon -0.10
Name: e, dtype: object
sort_index
obj = Series(range(4),index=['d','a','b','c'])
obj.sort_index()
#out:
a 1
b 2
c 3
d 0
dtype: int64
frame = DataFrame(np.arange(8).reshape((2,4)),index=['three','one'],columns=['d','a','b','c'])
frame.sort_index()
#out:
d a b c
one 4 5 6 7
three 0 1 2 3
frame.sort_index(axis=1)
# out:
a b c d
three 1 2 3 0
one 5 6 7 4
frame
# out:
d a b c
three 0 1 2 3
one 4 5 6 7
# 数据默认是按升序排序的,但也可以降序排列
frame.sort_index(axis=1,ascending=False)
# out:
d c b a
three 0 3 2 1
one 4 7 6 5
is_unique
判定索引的值是否重复
obj = Series(range(5),index=['a','a','b','b','c'])
obj.index.is_unique
sum
pandas 对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如sum
或mean
)或从DataFrame的行或列中提取一个Series。跟对应的Numpy数组方法相比,它们都是基于没有缺失数据的假设而构建的。
df = DataFrame([[1.4,np.nan],[7.1,-4.5],[np.nan,np.nan],[0.75,-1.3]],index=['a','b','c','d'],columns=['one','two'])
df
# out:
one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3
df.sum()
# out:
one 9.25
two -5.80
dtype: float64
df.sum(axis=1)
# out:
a 1.40
b 2.60
c 0.00
d -0.55
dtype: float64
NA值会自动被排除,除非整个切片(这里指的是行或列)都是NA。通过skipna选项可以禁用该功能
df.mean(axis=1,skipna=False)
# out:
a NaN
b 1.300
c NaN
d -0.275
dtype: float64
累积型的方法
df.cumsum()
既不是间接统计也不是累积型
df.describe()
unique
、value_counts
、isin
从一组数中抽取唯一值:unique
函数
u = obj.unique()
返回的值是无序的,如果需要排序,可以用u.sort()
value_counts
用于计算一个Series中各值出现的频率,默认情况下,Series统计出来的值是按降序排列的
obj.value_counts()
value_counts
还有一个顶级的pandas方法,可用于任何的数组或序列
pd.value_counts(obj.values,sort=False)
isin
,用于判断矢量化成员资格,可用于选取Series或DataFrame 中的数据子集
obj.isin(['1','3'])
将value_counts
与 apply
结合起来应用, DataFrame
没有 value_counts
方法
data.apply(pd.value_counts).fillna(0)
# out:
Qu1 Qu2 Qu3
1 1.0 1.0 1.0
2 0.0 2.0 1.0
3 2.0 2.0 0.0
4 2.0 0.0 2.0
5 0.0 0.0 1.0
dropna
缺失数据(missing data)在大部分数据分析应用中都很常见。pandas的设计目标之一就是让缺失数据的处理任务尽量轻松。例如,pandas对象上的所有描述统计都排除了缺失数据
pandas内置的none值也会当做缺失值处理
string_data = Series(['a','b',np.nan,'c'])
string_data
# out:
0 a
1 b
2 NaN
3 c
dtype: object
string_data.isnull()
# out:
0 False
1 False
2 True
3 False
dtype: bool
方法 | 说明 |
---|---|
dropna |
根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过阈(yu)值调节对缺失值的容忍度 |
fillna |
用指定值或插值方法(如ffill 或bfill )填充缺失数据 |
isnull |
返回一个含有布尔值的对象,这些布尔值表示哪些值是缺失值/NA,该对象的类型与源类型一样 |
notnull |
isnull 的否定式 |
利用dropna()
过滤掉缺失值,dropna
返回的是非空数据和索引值的Series
data = Series([1,np.nan,2])
data.dropna()
# Out:
0 1
2 2
DataFrame
中dropna
的处理复杂一点,默认丢弃包含NAN
的行
传入 how='all'
,将只丢弃全为NAN
的行
DataFrame
中dropna
只删除全部为NAN的某列的话,只需要传入一个:axis=1
即可
fillna
df
# Out:
one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3
df.fillna(0)
# Out:
one two
a 1.40 0.0
b 7.10 -4.5
c 0.00 0.0
d 0.75 -1.3
df.fillna({'one':1,'two':2})
# Out:
one two
a 1.40 2.0
b 7.10 -4.5
c 1.00 2.0
d 0.75 -1.3
fillna
默认会返回新对象,但也可以实现对原对象的修改
df.fillna(0,inplace=True)
split()
函数 拆分字符串strip()
函数 去空白字符,包括回车"字符"+
号进行字符串的连结join
in
检测子串 ,也可用index
和 find
count
返回子串出现的次数replace
替换,可以用空字符串来实现相当于删除的功能时间序列数据的意义取决于具体的应用场景,主要有以下几种:
from datetime import datetime
now = datetime.now()
now
# Out:
datetime.datetime(2019, 5, 23, 13, 49, 15, 480776)
now.year,now.month,now.day,now.hour,now.minute,now.second,now.microsecond
# Out:
(2019, 5, 23, 13, 49, 15, 480776)
delta = datetime(2011,1,7)-datetime(2008,6,24,8,15)
delta
# Out:
datetime.timedelta(days=926, seconds=56700)
delta.days
# Out:
926
delta.seconds
# Out:
56700
from datetime import timedelta
start = datetime(2011,1,7)
start
# Out:
datetime.datetime(2011, 1, 7, 0, 0)
start + timedelta(12)
# Out:
datetime.datetime(2011, 1, 19, 0, 0)
start - 2 * timedelta(12)
# Out:
datetime.datetime(2010, 12, 14, 0, 0)
2 * timedelta(12)
# Out:
datetime.timedelta(days=24)
stamp = datetime(2011,1,3)
str(stamp)
# Out:
'2011-01-03 00:00:00'
stamp.strftime('%Y-%m-%d')
# Out:
'2011-01-03'
value = '2011-01-03'
datetime.strptime(value,'%Y-%m-%d')
# Out:
datetime.datetime(2011, 1, 3, 0, 0)
datestrs = ['7/6/2011','8/6/2011']
[datetime.strptime(x,'%m/%d/%Y') for x in datestrs]
# Out:
[datetime.datetime(2011, 7, 6, 0, 0), datetime.datetime(2011, 8, 6, 0, 0)]
from dateutil.parser import parse
parse('2011-01-03')
# Out:
datetime.datetime(2011, 1, 3, 0, 0)
parse('Jan 31,1997 10:45 PM')
# Out:
datetime.datetime(2019, 1, 31, 22, 45)
parse('6/12/2011',dayfirst=True)
# Out:
datetime.datetime(2011, 12, 6, 0, 0)
parse('6/12/2011',dayfirst=False)
# Out:
datetime.datetime(2011, 6, 12, 0, 0)
pandas 通常是用于处理成组日期的,不管这些日期是DataFrame的轴索引还是列索引。
to_datetime方法可以解析多种不同的日期表示形式。对标准日期格式(如ISO8601)的解析非常快。
可以处理缺失值
NaT:(not a time) 是 pandas 中时间戳数据的NA值
pd.to_datetime(datestrs)
# Out:
DatetimeIndex(['2011-07-06', '2011-08-06'], dtype='datetime64[ns]', freq=None)
datestrs + [None]
# Out:
['7/6/2011', '8/6/2011', None]
idx = pd.to_datetime(datestrs + [None])
idx
# Out:
DatetimeIndex(['2011-07-06', '2011-08-06', 'NaT'], dtype='datetime64[ns]', freq=None)
idx[2]
# Out:
NaT
pd.isnull(idx)
# Out:
array([False, False, True])
pandas 最基本的时间序列类型就是以时间戳(通常以Python字符串或datetime对象表示)为索引的Series
dates =[datetime(2011,1,2),datetime(2012,2,3),datetime(2013,2,5),datetime(2014,4,6),datetime(2015,5,6),datetime(2016,4,6)]
ts = Series(np.random.randn(6),index=dates)
ts
# Out:
2011-01-02 -0.300655
2012-02-03 0.591874
2013-02-05 -1.414878
2014-04-06 -1.045828
2015-05-06 0.618211
2016-04-06 0.960725
dtype: float64
索引选取,子集构建
stamp = ts.index[2]
ts[stamp]
# Out:
-1.4148777980696403
ts['1/2/2011']
# Out:
-0.3006545366535157
ts['20110102']
# Out:
-0.3006545366535157
对于较长的时间序列,只需传入“年”或“年月”即可轻松选取数据的切片:
longer_ts = Series(np.random.randn(1000),index=pd.date_range('1/1/2000',periods=1000))
longer_ts['2001']
longer_ts['2001-04']
生成日期范围:date_range
默认情况下,date_range会产生按天计算的时间点,可以传入开始或结束日期来构造一段时间列表
index = pd.date_range('4/1/2012','5/1/2012')
index
# Out:
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
'2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
'2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
'2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
'2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20',
'2012-04-21', '2012-04-22', '2012-04-23', '2012-04-24',
'2012-04-25', '2012-04-26', '2012-04-27', '2012-04-28',
'2012-04-29', '2012-04-30', '2012-05-01'],
dtype='datetime64[ns]', freq='D')
pd.date_range(start='4/1/2012',periods=20)
# Out:
DatetimeIndex(['2012-04-01', '2012-04-02', '2012-04-03', '2012-04-04',
'2012-04-05', '2012-04-06', '2012-04-07', '2012-04-08',
'2012-04-09', '2012-04-10', '2012-04-11', '2012-04-12',
'2012-04-13', '2012-04-14', '2012-04-15', '2012-04-16',
'2012-04-17', '2012-04-18', '2012-04-19', '2012-04-20'],
dtype='datetime64[ns]', freq='D')
pd.date_range(end='6/1/2012',periods=20)
# Out:
DatetimeIndex(['2012-05-13', '2012-05-14', '2012-05-15', '2012-05-16',
'2012-05-17', '2012-05-18', '2012-05-19', '2012-05-20',
'2012-05-21', '2012-05-22', '2012-05-23', '2012-05-24',
'2012-05-25', '2012-05-26', '2012-05-27', '2012-05-28',
'2012-05-29', '2012-05-30', '2012-05-31', '2012-06-01'],
dtype='datetime64[ns]', freq='D')
pandas 对象中的数据可以通过一些内置的方式进行合并;
pandas.merge 可根据一个或多个键将不同DataFrame中的行连接起来。SQL或其他关系型数据库的用户对此应该会比较熟悉,因为它实现的就是数据库的连接操作。
pandas.concat 可以沿着一条轴将多个对象堆叠到一起。
combine_first 可以将重复数据编接在一起,用一个对象中的值填充另一个对象中的缺失值。
df1 = DataFrame({'key':['b','b','a','c','a','a','b'],'data1':range(7)})
df2 = DataFrame({'key':['a','b','d'],'data2':range(3)})
df1
# Out:
key data1
0 b 0
1 b 1
2 a 2
3 c 3
4 a 4
5 a 5
6 b 6
df2
# Out:
key data2
0 a 0
1 b 1
2 d 2
# 默认情况下,merge采用的是"inner连结",取交集部分,没有交集的会舍弃掉
pd.merge(df1,df2)
# Out:
key data1 data2
0 b 0 1
1 b 1 1
2 b 6 1
3 a 2 0
4 a 4 0
5 a 5 0
pd.merge(df1,df2,on='key')
# Out:
key data1 data2
0 b 0 1
1 b 1 1
2 b 6 1
3 a 2 0
4 a 4 0
5 a 5 0
df3 = DataFrame({'lkey':['b','b','a','c','a','a','b'],'data1':range(7)})
df4 = DataFrame({'rkey':['a','b','d'],'data2':range(3)})
# 如果两个对象的列名不同,也可以分别进行指定:
pd.merge(df3,df4,left_on='lkey',right_on='rkey')
# Out:
lkey data1 rkey data2
0 b 0 b 1
1 b 1 b 1
2 b 6 b 1
3 a 2 a 0
4 a 4 a 0
5 a 5 a 0
# 可以通过merge的how参数来指定左连接,右连接合外连接.
# how=outer,是取数据集的并集,组合了左连结与右连结的结果
pd.merge(df1,df2,how='outer') # 外连接
# Out:
key data1 data2
0 b 0.0 1.0
1 b 1.0 1.0
2 b 6.0 1.0
3 a 2.0 0.0
4 a 4.0 0.0
5 a 5.0 0.0
6 c 3.0 NaN
7 d NaN 2.0
pd.merge(df1,df2,how='left') # 左连接
# Out:
key data1 data2
0 b 0 1.0
1 b 1 1.0
2 a 2 0.0
3 c 3 NaN
4 a 4 0.0
5 a 5 0.0
6 b 6 1.0
pd.merge(df1,df2,how='right') # 右连接
# Out:
key data1 data2
0 b 0.0 1
1 b 1.0 1
2 b 6.0 1
3 a 2.0 0
4 a 4.0 0
5 a 5.0 0
6 d NaN 2
left = DataFrame({'key1':['foo','foo','bar'],
'key2':['one','two','one'],
'lval':[1,2,3]})
right = DataFrame({
'key1':['foo','foo','bar','bar'],
'key2':['one','one','one','two'],
'rval':[4,5,6,7]
})
left
# Out:
key1 key2 lval
0 foo one 1
1 foo two 2
2 bar one 3
right
# Out:
key1 key2 rval
0 foo one 4
1 foo one 5
2 bar one 6
3 bar two 7
pd.merge(left,right,on=['key1','key2'],how='outer')
# Out:
key1 key2 lval rval
0 foo one 1.0 4.0
1 foo one 1.0 5.0
2 foo two 2.0 NaN
3 bar one 3.0 6.0
4 bar two NaN 7.0
concat
s1 = Series([0,1],index=['a','b'])
s2 = Series([2,3,4],index=['c','d','e'])
s3 = Series([5,6],index=['f','g'])
pd.concat([s1,s2,s3])
# Out:
a 0
b 1
c 2
d 3
e 4
f 5
g 6
dtype: int64
默认情况下,concat 是在 axis= 0 上工作,最终产生一个Series,如果传入axis=1,则最终产生一个DataFrame(axis=1在列上工作)
pd.concat([s1,s2,s3],axis=1)
# Out:
0 1 2
a 0.0 NaN NaN
b 1.0 NaN NaN
c NaN 2.0 NaN
d NaN 3.0 NaN
e NaN 4.0 NaN
f NaN NaN 5.0
g NaN NaN 6.0
可以利用concat函数的join= inner 参数来取两个连接的交集
pd.concat([s1,s4],axis=1,join='inner')
# Out:
0 1
a 0 0
b 1 5
如果想在连接轴上创建层次索引,可以给keys传入一个列表
pd.concat([s1,s2,s3],keys=['one','two','three'])
# Out:
one a 0
b 1
two c 2
d 3
e 4
three f 5
g 6
dtype: int64
有一种数据组合问题不能用简单的合并(merge)或连接(concat)运算来处理,比如:索引全部或部分重叠的两个数据集
Series中有一个方法可以实现重叠数据的对齐
a = Series([np.nan,2.5,np.nan,3.5,4.5,np.nan],index=['f','e','d','c','b','a'])
b = Series(np.arange(len(a),dtype=np.float64),index=['f','e','d','c','b','a'])
b[:-2].combine_first(a[2:])
# Out:
a NaN
b 4.5
c 3.0
d 2.0
e 1.0
f 0.0
dtype: float64
DataFrame,combine_first 也会在列上做同样的事情,因此可以看做参数对象中的数据为调用者对象的确实数据“打补丁”
df1 = DataFrame({'a':[1.,np.nan,5.,np.nan],
'b':[np.nan,2.,np.nan,6.],
'c':range(2,18,4)})
df2 = DataFrame({'a':[5.,4.,np.nan,3.,7.],
'b':[np.nan,3.,4.,6.,8.]})
df1.combine_first(df2)
# Out:
a b c
0 1.0 NaN 2.0
1 4.0 2.0 6.0
2 5.0 4.0 10.0
3 3.0 6.0 14.0
4 7.0 8.0 NaN
data = Series(np.random.rand(10),index=[['a','a','a','b','b','b','c','c','d','d'],
[1,2,3,1,2,3,1,2,2,3]])
data
Out:
a 1 0.621196
2 0.545708
3 0.553969
b 1 0.923237
2 0.471105
3 0.680784
c 1 0.903870
2 0.576824
d 2 0.600520
3 0.143685
dtype: float64
stack
: 将数据的列“旋转”为行
unstack
:将数据的行“旋转”为列
data = DataFrame(np.arange(6).reshape((2,3)),index=pd.Index(['Ohio','Colorado'],name='state'),
columns=pd.Index(['one','two','three'],name='number'))
data
# Out:
number one two three
state
Ohio 0 1 2
Colorado 3 4 5
data.stack()
# Out:
state number
Ohio one 0
two 1
three 2
Colorado one 3
two 4
three 5
dtype: int64
data.unstack()
# Out:
number state
one Ohio 0
Colorado 3
two Ohio 1
Colorado 4
three Ohio 2
Colorado 5
dtype: int64
默认情况下,unstack操作的是最内层(stack也是如此)。传入分层级别的编号或名称即可对其他级别进行unstack操作
result = data.stack()
result
# Out
state number
Ohio one 0
two 1
three 2
Colorado one 3
two 4
three 5
dtype: int64
result.unstack()
# Out:
number one two three
state
Ohio 0 1 2
Colorado 3 4 5
result.unstack(0) # 0代表最外层
# Out:
state Ohio Colorado
number
one 0 3
two 1 4
three 2 5
result.unstack('state')
# Out:
state Ohio Colorado
number
one 0 3
two 1 4
three 2 5
stack
和 unstack
是可逆的
drop_duplicates
DataFrame的duplicated
方法返回一个布尔型Series,表示各行是否是重复行;
drop_duplicates
方法,它用于返回一个移除了重复行的DataFrame;
这两个方法默认会判断全部列,也可以指定部分列进行重复项判断。
data = DataFrame({'k1':['one']*3 + ['two']*4,'k2':[1,1,2,3,3,4,4]})
data
# Out:
k1 k2
0 one 1
1 one 1
2 one 2
3 two 3
4 two 3
5 two 4
6 two 4
data.duplicated()
# Out:
0 False
1 True
2 False
3 False
4 True
5 False
6 True
dtype: bool
data.drop_duplicates()
# Out:
k1 k2
0 one 1
2 one 2
3 two 3
5 two 4
data['v1'] = range(7)
data
# Out:
k1 k2 v1
0 one 1 0
1 one 1 1
2 one 2 2
3 two 3 3
4 two 3 4
5 two 4 5
6 two 4 6
data.drop_duplicates(['k1'])
# Out:
k1 k2 v1
0 one 1 0
3 two 3 3
# 默认保留的是第一个出现的值组合,如果要改变,传入 `keep`参数
data.drop_duplicates(['k1'],keep='first')
# Out:
k1 k2 v1
2 one 2 2
6 two 4 6
map
fillna
、replace
cut
、qcut
为了便于分析,连续数据常常被离散化或拆分为“面元”(bin)
qcut : 可以根据样本分位数对数据进行面元拆分,可以得到大小基本相等的面元。
参考网址: https://blog.csdn.net/tcy23456/article/details/84797418
ages = [20,22,25,27,21,23,37,31,61,45,41,32]
bins = [18,25,35,60,100]
cats = pd.cut(ages,bins)
pd.cut(data,4,precision=2) # 等长、均匀分布面元拆分
read_csv
read_csv:默认逗号分隔,默认首行作为列名称
df = pd.read_csv('test.csv')
pd.read_csv( )
读取没有明显 列名称的文件,就不让首行 为 列名称。参数 header = None
df = pd.read_csv('test.csv' ,header=None)
自定义 列名称 ,参数 names = [ ]
df = pd.read_csv('test.csv' ,names = ['a','b','c','d','message'])
names=[]
的长度不匹配 列数量,会自动把 names
匹配到最后,数量不足的都是 行索引index
df = pd.read_csv('test.csv' ,names = ['aa','bb','cc'])
# Out:
aa bb cc
1 2 3 4 hello
5 6 7 8 world
9 10 11 12 foo
names=[]
的长度超出列数量,会匹配列,超出部分都是 Nan
df = pd.read_csv('test.csv' ,names = ['aa','bb','cc','dd','ee','ff','gg'])
自己 设置 某列的值为 行索引 ,参数: index_col = ''
df = pd.read_csv('test.csv' ,names = ['aa','bb','cc','dd','message'] ,index_col ='message')
设置多列作为 行索引
df = pd.read_csv('test.csv' ,index_col = ['key1','key2'])
使用参数 skiprows = []
, 实现 跳过某些无效行或者 注释 行
df = pd.read_csv('test.csv',skiprows=[0,2,3])
读取的时候让 xxx 为 nan , na_values = [ xxx,yyy,...]
df = pd.read_csv('test.csv',na_values=[2,12])
指定不同的 列 的 不同的 值 为 nan ,参数 na_values = { '列名称':'具体值' ,... }
nans = {'something':['two'] ,'message':['foo','world'] }
df = pd.read_csv('test.csv',na_values=nans)
读取的数据是纯字符串的,可以用 dtype =
指明 类型
df = pd.read_csv('test.csv',dtype=int)
选取几列 读出来 , usecols = []
df = pd.read_csv('data/ex7.csv',dtype=int ,usecols=['a','c'])
也可以是 先 读取整体 ,再 提取几列,更为灵活
df[['a','c']]
read_table
read_table :需要指定分隔符sep=','
,默认首行作为列名称,读取 不规则 的 分隔符数据。用 正则 表达式 作为 分隔符。不需要导入 re,不需要创建 对象
df = pd.read_table('test.csv',sep=',')
df = pd.read_table('test.csv',sep='\s+')
read_clipboard
读取剪贴板的内容
pd.read_clipboard()
.to_csv()
df = DataFrame(
np.random.randint(40,100,(25,4)),
index = range(1,26),
columns = '语文,数学,英语,体育'.split(',')
)
# 默认存储 .行列索引都存储
df.to_csv( 'out1.csv')
DataFrame([[10,20,30],[20,40,60,70]]).to_csv('out2.csv')
# 参数 header = False 。不存 column
df.to_csv('out4.csv',index=False ,header=False)
# 如果数据中 有 nan
# 参数 na_rep = ' ' nan换成 xxx 显示
df.to_csv('out5.csv',na_rep='Null')
.to_excel()
xxx.to_excel(excel_writer, sheet_name='Sheet1', na_rep='',。。。。)
excel_writer:文件名
sheet_name: 存的时候表的名称
其他参数同 csv
预览 sys.stdout .然后再写存储
df.to_csv(sys.stdout ,index=False)