Series对象
Series可以用下标和索引标签存取元素。每个Series对象实际上都由两个数组组成:index:他是从ndarry数组继承的Index索引对象,保存标签信息。若创建Series对象时不指定index,将自动创建一个表示位置下标的索引。
- values:保存元素值得ndarry数组,Numpy的函数都对此数组进行处理。
import pandas as pd
import numpy as np
s = pd.Series(np.arange(5), index=["a", "b", "c", "d", "e"])
print u"索引", s.index
print U"值数组", s.values
索引 Index([u'a', u'b', u'c', u'd', u'e'], dtype='object')
值数组 [0 1 2 3 4]
print s[2]#支持位置和标签两种形式
print s["c"]
2
2
print s[1:3]#支持切片,但标签切片同时包含起始标签和结束标签
print s["b":"d"]
b 1
c 2
dtype: int32
b 1
c 2
d 3
dtype: int32
print s[[1, 3, 2]]#可以使用位置列表或位置数组存取元素
print s[['a', 'b', 'c']]
b 1
d 3
c 2
dtype: int32
a 0
b 1
c 2
dtype: int32
print list(s.iteritems())#同时具有数组和字典的功能
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4)]
s2 = pd.Series([20, 30, 40, 50, 60], index=['b', 'c', 'd', 'e', 'f'])
print s+s2#当两个Series对象进行操作符运算时,Pandas会按照标签对齐元
#素,也就是运算操作符会对标签相同的两个元素进行计算,当某一方标签不存在
#时,默认一Nan填充
a NaN
b 21.0
c 32.0
d 43.0
e 54.0
f NaN
dtype: float64
1.基本用法
- Dataframe对象
import pandas as pd
df_soil = pd.read_csv("C:\\WHO_first9cols.csv", index_col=[0])#index_col指定第一列为行索引
print df_soil.dtypes
print df_soil.shape
print df_soil.index #行索引
print df_soil.columns #列索引
print df_soil['CountryID'] #下标是单个标签时,所得到的是Series对象,
print df_soil[['CountryID', 'Continent']] #下标是列表时,则得到一个新的DataFrame对象
print df_soil.loc['Afghanistan'] #通过.loc可以获得行所对应的内容,单个为Series对象,多个位DataFrame对象
print df_soil.values #将对象转换为数组,本例中类型不一致,统一转为object对象
2.将内存中数据转换为DataFrame对象,他的三个参数分别为data,index,columns分别为数据、行索引和列索引。
import pandas as pd
import numpy as np
df1 = pd.DataFrame(np.random.randint(0, 10, (4, 2)), index=['A', 'B', 'C', 'D'], columns=['a', 'b'])
#将二维数组转换为df,行列通过index, columns指定
df2 = pd.DataFrame({'a':[1, 2, 3, 4], "b":[5, 6, 7, 8]}, index=["A", "B", "C", "D"])
#将字典转为df对象,列索引由键指定,行索引index指定
arr = np.array([('item1', 1), ('item2', 2), ('item3', 3)], dtype=[("name", "10S"), ("count", int)])
#将结构数组转换为df对象,其列索引由结构数组的字段名决定,行索引为默认从0开始的整数序列
df3 = pd.DataFrame(arr)
print df1
print df2
print df3
a b
A 6 6
B 9 5
C 1 5
D 2 8
a b
A 1 5
B 2 6
C 3 7
D 4 8
name count
0 item1 1
1 item2 2
2 item3 3
此外还可以调用以from_开头的类方法,将特定格式的数据转换成DataFrame对象。
import pandas as pd
import numpy as np
dict1 = {"a": [1, 2, 3], "b": [4, 5, 6]}
dict2 = {"a": {"A": 1, "B": 2}, "b": {"A": 3, "C":4}}
#orident指定字典键对应的方向,默认为"columns"
df1 = pd.DataFrame.from_dict(dict1, orient="index")
df2 = pd.DataFrame.from_dict(dict1, orient="columns")
df3 = pd.DataFrame.from_dict(dict2, orient="index")#嵌套时第一重为指定的键,缺失值为NaN
df4 = pd.DataFrame.from_dict(dict2, orient="columns")
print df1
print df2
print df3
print df4
items = dict1.items()
'''
将键值序列转换为DataFrame对象,其中值是表示一维数据的列表、数组或Series对象。当其中orient
参数为index时,需要通过columns指定列索引。
'''
dfi1 = pd.DataFrame.from_items(items, orient='index', columns=["A", "B", "C"])
dfi2 = pd.DataFrame.from_items(items, orient="columns")
0 1 2
a 1 2 3
b 4 5 6
a b
0 1 4
1 2 5
2 3 6
A B C
a 1 2.0 NaN
b 3 NaN 4.0
a b
A 1.0 3.0
B 2.0 NaN
C NaN 4.0
3.将DataFrame转换为其他格式的数据
import pandas as pd
dict = {"a": {"A": 1, "B": 2}, "b": {"A": 3, "C":4}}
df = pd.DataFrame.from_dict(dict, orient="columns")
print df
print u"字典列表", df.to_dict(orient="records")
print u"列表字典", df.to_dict(orient="list")
print u"嵌套字典", df.to_dict(orient="dict")
a b
A 1.0 3.0
B 2.0 NaN
C NaN 4.0
字典列表 [{'a': 1.0, 'b': 3.0}, {'a': 2.0, 'b': nan}, {'a': nan, 'b': 4.0}]
列表字典 {'a': [1.0, 2.0, nan], 'b': [3.0, nan, 4.0]}
嵌套字典 {'a': {'A': 1.0, 'C': nan, 'B': 2.0}, 'b': {'A': 3.0, 'C': 4.0, 'B': nan}}
to_records()方法可以将DataFrame对象转为结构数组。
import pandas as pd
dict = {"a": {"A": 1, "B": 2}, "b": {"A": 3, "C":4}}
df = pd.DataFrame.from_dict(dict, orient="columns")
print df
print u"字典列表", df.to_dict(orient="records")
print u"列表字典", df.to_dict(orient="list")
print u"嵌套字典", df.to_dict(orient="dict")
4.Index对象。Index对象保存索引标签数据,它可以快速找到标签对应的整数下标。
import pandas as pd
dict = {"a": {"A": 1, "B": 2}, "b": {"A": 3, "C":4}}
df = pd.DataFrame.from_dict(dict, orient="columns")
print df
index = df.columns
print index.values
#index可以当做一维数组用
print index[[1]]
print index[index > 'a']
#index对象也具有字典的映射功能,他将数组中的值映射到其他位置。
print index.get_loc('a') #获取下标
print index.get_indexer(['a', 'b']
#index不可变,多个对象的索引可以有一个index提供
a b
A 1.0 3.0
B 2.0 NaN
C NaN 4.0
['a' 'b']
Index([u'b'], dtype='object')
Index([u'b'], dtype='object')
0
[0 1]
5.MultiIndex对象,多级索引,其中的多级标签采用元组对象表示。
import pandas as pd
import numpy as np
class1 = ["A", "A", "B", "B"]
class2 = ["x", "y", "x", "y"]
midx = pd.MultiIndex.from_product([["A", "B", "C"], ["x", "y"]], names=["class1", "class2"])
#从多个集合的笛卡尔积创建MultiIndex对象。
df = pd.DataFrame(np.random.randint(0, 10, (6, 6)), columns=midx, index=midx)
print df
class1 A B C
class2 x y x y x y
class1 class2
A x 6 7 6 7 1 1
y 6 2 1 9 6 2
B x 9 0 4 6 5 4
y 9 0 9 5 4 8
C x 2 1 3 5 7 1
y 4 9 1 0 3 2
6.query()方法:当需要根据一定的条件进行过滤时,通常可以先创建一个布尔数组,使用该数组获取True对应的行。由于python中无法自定义not、and、or,因此需要改用~、&、!等位运算符。这些运算符优先级比比较运算符高,因此要加括号
df[(df.ph > 5) & (df.ca < 11))
使用query可以简化上诉程序:
fd.query("ph>5 and ca < 11") #可以使用and or not
7.文件读写
函数名 | 说明 |
---|---|
read_csv() | 从csv格式的文本文件读取数据 |
read_excel() | 从Excel文件读取数据 |
HDFStore() | 使用HDF5文件读写数据 |
read_sql() | 从SQL数据库的查询结果载入数据 |
read_pickle() | 读入pickle()序列化后的数据 |
- csv文件
read_scv()文件的参数
- sep参数指定数据的分隔符号,默认使用逗号。有时CSV文件为便于阅读,在逗号后添加了一些空格以对齐数据。如果希望忽略可以将skipinitialspace参数设置为True.
- 如果数据使用空格或制表符分割,可以不设置sep参数,而将delim_whitespace参数设置为True.
- 默认情况下第一行文本被设置为列索引标签,如果数据文件没有保存列名的行,可以设置header参数为None.
- 如果数据文件前包含一些说明行,可以使用skiprows参数指定数据开始的行号。
- na_values、true_values和false_values等参数分别指定NaN、True、和False对应的字符串列表。
- io.BytesIO(string)可以将字符串包装成输入流。
- parse_dates可以将字符串转换为时间。
- encoding参数指定文件的编码。
- usecols参数指定需要读入的列。
import pandas as pd
df_list = []
for df in pd.read_csv(
"c:\\WHO_first9cols.csv",
encoding="utf-8", #编码格式
usecols=[0, 1, 4], #选择那几列
parse_dates=[2], #转为时间格式,文件中为第4列,选中的第2列
chunksize=100,): #每次读100行
df_list.append(df)
print df_list
- HDF5文件,HDF5文件像一个保存数据的文件系统,其中只有两种类型的对象:资料数据和目录。
import pandas as pd
import numpy as np
store = pd.HDFStore("C:\\a.hdf5", complib="blosc", complevel=9)
df1 = pd.DataFrame(np.random.rand(100000, 4), columns=list("ABCD"))
df2 = pd.DataFrame(np.random.randint(0, 1000, (1000, 3)), columns=["one", "two", "there"])
s1 = pd.Series(np.random.rand(1000))
store["dataframes/df1"] = df1
store["dataframes/df2"] = df2
store["series/s1"] = s1
print store.keys()
#_f_walknodes()可以遍历其包含的所有节点,
root = store.get_node("//")
for node in root._f_walknodes():
print node
#append可以实现添加数据的功能。
#append参数为False表示覆盖已存在的数据,如果指定键不存在可以忽略该参数。
store.append('dataframes/df_dynamic1', df1, append=False)
df3 = pd.DataFrame(np.random.rand(100, 4), columns=list("ABCD"))
store.append('dataframes/df_dynamic1', df3) #将df3追加到指定键
print store['dataframes/df_dynamic1'].shape
#使用append()强创建pytables中文支持索引的表格节点,默认使用DataFrame的index做为索引。
#通过select()可以对表格进行查询,以获取满足查询条件的行。
print store.select("dataframes/df_dynamic1", where='index > 97 & index < 102')
#如果希望dataframe的指定的列索引,可以在用append()创建新的表格时,通过data_columns制定索引列,或将其设置为True以对所有列创建索引。
store.append('dataframes/df_dynamic1', df1, append=False, data_columns=["A", "B"])
print store.select('dataframes/df_dynamic1', where='A > 0.99 & B <0.01')
8.数值计算函数
Series和DataFrame对象都支持Numpy的数组接口,因此可直接用Numpy提供的ufunc函数对他们进行计算。这些函数都有如下三个常数:
- axis:指定运算对应的轴
- level:指定运算对应的索引级别
- skipna:运算是否自动跳过NaN
Pandas还提供了rolling_*()函数来对序列中相邻的N个元素进行移动窗口运算。下面是对带脉冲噪声的正弦波进行处理的结果。他们的第二个参数为窗口包含的元素个数,而center参数为True表示移动窗口以当前元素为中心。
import numpy as np
import pandas as pd
t = np.linspace(0, 10, 400)
x = np.sin(0.5*2*np.pi*t)
x[np.random.randint(0, len(t), 40)] += np.random.normal(0, 0.5, 40)
s = pd.Series(x, index=t)
s_mean = s.rolling(5, center=True).mean() #实现移动平均
s_median = s.rolling(5, center=True).median() #实现中值滤波
from matplotlib import pyplot as plt
plt.plot(t, x, label=u"噪声信号")
plt.plot(t, s_mean, label=u"移动平均")
plt.plot(t, s_median, label=u"中值滤波")
plt.legend()
plt.savefig("C:\\figure1.png")
9.字符串处理
import pandas as pd
s = pd.Series(['a', 'b', 'c'])
print s.str.upper()
s_utf8 = pd.Series([b"北京", b"北京市", b"北京地区"])
s_unicode = s_utf8.str.decode("utf-8")
s_gb2312 = s_unicode.str.encode("gb2312")
print s_utf8.str.len() #UTF-8一个汉字占3个字节
print s_unicode.str.len() #实际的汉子格式
print s_gb2312.str.len() #一个汉字占两个字节
#无论Series对象包含那种字符串对象,其dtype属性都是object,因袭无法根据他判断字符串类型。
s = pd.Series(["a|bc|de", "x|xyz|yz"])
s_list = s.str.split("|")
s_comma = s_list.str.join(",")
print s_list
print s_comma
处理特定分隔符分割关键字的数据:
import io
import pandas as pd
import numpy as np
text = """
A, B|C|D
B, E|F
C, A
D, B|C
"""
df = pd.read_csv(io.BytesIO(text), skipinitialspace=True, header=None)
print df
nodes = df[1].str.split("|")
print nodes.str.len()
'''
0 3
1 2
2 1
3 2
'''
from_node = df[0].values.repeat(nodes.str.len().astype(np.int32))
#调用numpy的repeat()方法将第一列的数据重复相应的次数,repeat只接受32位的数据
to_nodes = np.concatenate(nodes)#将嵌套列表平坦化,转为一维数组。
astype()转换数据类型
print pd.DataFrame({"from_node":from_node, "to_node":to_nodes})
'''
还可以吧第二列看做第一列数据的标签,为了后续分析,通常用str.get_dummies()将这种
数据转换为布尔DataFrame对象,每一列与一个标签对应,元值为1表示对应的行包含对应的标签
'''
print df[1].str.get_dummies(sep="|")
0 1
0 A B|C|D
1 B E|F
2 C A
3 D B|C
0 3
1 2
2 1
3 2
Name: 1, dtype: int64
from_node to_node
0 A B
1 A C
2 A D
3 B E
4 B F
5 C A
6 D B
7 D C
A B C D E F
0 0 1 1 1 0 0
1 0 0 0 0 1 1
2 1 0 0 0 0 0
3 0 1 1 0 0 0
10.时间序列:
import pandas as pd
#Period是一个标准的时间段
now_day = pd.Period.now(freq='D')
now_hour = pd.Period.now(freq="H")#具体到小时,无分钟
print now_day
print now_hour
perid = pd.Period.now(freq="W") #以周天未开始的星期时间段
print perid.start_time, perid.end_time #获取时间段的开始时间和结束时间
#调用Timestamp对象的to_period()方法可以把时间点转换为包含该时间点的时间段。
now = pd.Timestamp.now()
print now.to_period("H")
#将两个时间点相减可以得到表示时间间隔的Timedelta对象。
national_day = pd.Timestamp("2017-10-1")
td = national_day - pd.Timestamp.now()
print td
#时间点和时间间隔之间可以进行加减计算:
print national_day + pd.Timedelta("268 days 13:27:07")
#也可以通过关键字参数直接指定时间间隔的天数、小时数、分钟数
print pd.Timedelta(days=10, hours=1, minutes=2, seconds=10.5)
print pd.Timedelta(seconds=100000)