8. Pandas的DataFrame创建
Pandas的Dataframe是二维的,每一列都是一个Series结构。
8.1 字典数据创建DataFrame
DataFrame数据的创建和Series的创建类似,可以有很多方式。和Series一样也有字典类型的方式。
- 字典方式创建DataFrame
import pandas as pd
df = pd.DataFrame({'name' : "hello the cruel world".split(),
'growth' : [100, 125, 150, 200]},
index = "jack tom mike nike".split())
print df
执行结果如下:
growth name
jack 100 hello
tom 125 the
mike 150 cruel
nike 200 world
最左侧的一列是index或者label和Series类似,第二列是growth列,第三列是name列。growth和name为该列的名字。需要特别注意的是DataFrame和其他表格数据不一样的是,DataFrame是列访问机制。例如要访问growth下的150这条数据的访问方式为:
import pandas as pd
df = pd.DataFrame({'name' : "hello the cruel world".split(),
'growth' : [100, 125, 150, 200]},
index = "jack tom mike nike".split())
print df['growth']['mike']
print df.growth['mike']
print df.name,type(df.name)
print df["name"]
程序执行结果:
150
150
jack hello
tom the
mike cruel
nike world
Name: name, dtype: object <class 'pandas.core.series.Series'>
jack hello
tom the
mike cruel
nike world
Name: name, dtype: object
df.name是Series的,这点儿很重要。
8.2 Numpy数据创建DataFrame
- 通过numpy数据建立DataFrame
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.randn(10,3), columns = ["ca", "cb", "cc"], index = list("abcdefghij"))
print df
程序执行结果:
ca cb cc
a -1.445673 -0.856954 -0.085766
b -0.276927 -0.181103 -1.120856
c 1.155409 0.114528 1.514519
d -0.304959 -1.099241 -0.018434
e 0.458164 -0.550848 0.396272
f -0.362203 -0.383894 -0.444436
g -0.755501 -0.148579 -0.910084
h -0.666200 0.713844 1.822668
i -1.278918 -2.055927 -0.404884
j 0.340294 1.437949 -0.119828
DataFrame构造函数的columns函数给出列的名字,index给出label标签或index位置信息,创建DataFrame的数据是numpy创建的二维的数据。
8.3 csv文件创建DataFrame
- 从csv文件读取DataFrame数据,这里可以使用机器学习经典数据集iris.data数据作为测试数据,下载。iris.data文件的内容:
5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
可以使用pandas的read_csv函数来读取这个文件里的数据到DataFrame数据里。
import pandas as pd
cols_name = ['sepal length', 'sepal width', 'petal length', 'petal width', 'class']
df = pd.read_csv("iris.data", names = cols_name)
print df
程序执行结果:
sepal length sepal width petal length petal width class
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosa
2 4.7 3.2 1.3 0.2 Iris-setosa
3 4.6 3.1 1.5 0.2 Iris-setosa
iris.data文件里都是数据,而有些csv文件的第一行会给出每列数据的名字,例如股票交易信息类的csv文件通常都这样给出csv记录,可以从Nasdaq下载jd的历史交易记录,下载后存为jd.csv好了,和.py程序存储在同一个目录下。jd.csv的内容大致如下:
"date","close","volume","open","high","low"
"10:24","22.585","3,018,583","23.18","23.20","22.515"
"2018/10/23","23.2300","17943360.0000","22.6100","23.5900","22.3300"
"2018/10/22","23.5400","13934080.0000","23.8600","24.1100","23.3000"
"2018/10/19","23.0100","12953670.0000","23.9400","23.9499","22.9500"
"2018/10/18","23.3300","15580080.0000","23.5000","24.1321","23.2200"
它的第一行显然不是数据而是说明每列的数据是什么,这行数据是不能读入到DataFrame里的,应忽略掉。可以用pandas的read_csv先读一下这个文件。
import pandas as pd
df = pd.read_csv("jd.csv")
print df
程序执行结果如下:
date close volume open high low
0 10:24 22.585 3,018,583 23.180 23.2000 22.5150
1 2018/10/23 23.230 17943360.0000 22.610 23.5900 22.3300
2 2018/10/22 23.540 13934080.0000 23.860 24.1100 23.3000
3 2018/10/19 23.010 12953670.0000 23.940 23.9499 22.9500
4 2018/10/18 23.330 15580080.0000 23.500 24.1321 23.2200
5 2018/10/17 23.680 15368750.0000 24.520 24.6100 23.4600
6 2018/10/16 24.630 11679180.0000 24.500 24.7000 24.0800
7 2018/10/15 24.140 11132030.0000 24.110 24.6400 23.8000
8 2018/10/12 24.450 20191050.0000 24.540 24.9000 23.7400
这里有几个问题,1). index是自动用数字作为各行数据的index或label,一般应该用date做index或label作为股票分析时使用比较好,2).如果jd.csv文件的头几行是文件的说明,那么read_csv读的时候也会当作数据,这时应能忽略掉头几行非数据的信息。3). 数据读入后类型是否正确读出?
import pandas as pd
df = pd.read_csv("jd.csv", index_col = 0)
print df[:5]
print df.dtypes
程序执行结果:
close volume open high low
date
10:24 22.585 3,018,583 23.18 23.2000 22.515
2018/10/23 23.230 17943360.0000 22.61 23.5900 22.330
2018/10/22 23.540 13934080.0000 23.86 24.1100 23.300
2018/10/19 23.010 12953670.0000 23.94 23.9499 22.950
2018/10/18 23.330 15580080.0000 23.50 24.1321 23.220
close float64
volume object
open float64
high float64
low float64
dtype: object
-
指定某列为label,通过指定read_csv函数的index_col形参为数据的第一列作为DataFrame的index或label,可将第一列date作为df这个DataFrame的label,避免用自动分配的整型数据作为label。
-
skiprows参数,volume的数据类型是object,很诡异,应该是数值型的数据比较好,所以在读入数据时可以指定相应列的数据类型。由于数据里的第1行的volume是' 3,018,583'这条数据和其下的其他数据的表示形式不一致,所以可以使用skiprows参数忽略这行数据。
import numpy as np
import pandas as pd
df = pd.read_csv("jd.csv", index_col = 0, dtype = {'volume' : np.float64},skiprows=[1])
print df[:5]
print df.dtypes
程序执行结果:
close volume open high low
date
2018/10/23 23.23 17943360 22.61 23.5900 22.33
2018/10/22 23.54 13934080 23.86 24.1100 23.30
2018/10/19 23.01 12953670 23.94 23.9499 22.95
2018/10/18 23.33 15580080 23.50 24.1321 23.22
2018/10/17 23.68 15368750 24.52 24.6100 23.46
close float64
volume float64
open float64
high float64
low float64
dtype: object
- header参数和names参数,数据里的第0行、第1行数据,一个是各字段名,和当日交易,pandas的read_csv会把第0行作为各个字段的名,也可自己指定字段名,忽略掉第0行的数据。
import numpy as np
import pandas as pd
df = pd.read_csv("jd.csv", index_col = 0, dtype = {'volume' : np.float64},skiprows=[0,1], header = 0, names = ["Close","Volume","Open","High","Low"])
print df[:5]
print df.dtypes
执行结果:
Close Volume Open High Low
2018/10/22 23.54 13934080 23.86 24.1100 23.30
2018/10/19 23.01 12953670 23.94 23.9499 22.95
2018/10/18 23.33 15580080 23.50 24.1321 23.22
2018/10/17 23.68 15368750 24.52 24.6100 23.46
2018/10/16 24.63 11679180 24.50 24.7000 24.08
Close float64
Volume float64
Open float64
High float64
Low float64
dtype: object
- usecols参数,以上的例子是将数据全部读入,也可通过指定usecols参数,读入部分列的数据。
import numpy as np
import pandas as pd
df = pd.read_csv("jd.csv",
skiprows=[1],
usecols = ['date','close', 'volume','open'],
index_col = 0,
dtype = {'volume' : np.float64})
print df[:5]
print df.dtypes
程序执行结果:
close volume open
date
2018/10/23 23.23 17943360 22.61
2018/10/22 23.54 13934080 23.86
2018/10/19 23.01 12953670 23.94
2018/10/18 23.33 15580080 23.50
2018/10/17 23.68 15368750 24.52
close float64
volume float64
open float64
dtype: object
- read_table函数,pandas里除了read_csv还有read_table函数也可以读取csv文件成DataFrame。
import pandas as pd
df = pd.read_csv("movies.dat", sep = "::",engine='python', index_col = 0)
print df[:5]
movies.dat文件可以从movielen下载,每天记录以::
分割字段,部分内容如下。
1::Toy Story (1995)::Animation|Children's|Comedy
2::Jumanji (1995)::Adventure|Children's|Fantasy
3::Grumpier Old Men (1995)::Comedy|Romance
4::Waiting to Exhale (1995)::Comedy|Drama
5::Father of the Bride Part II (1995)::Comedy
通过read_table读回的数据:
Toy Story (1995) Animation|Children's|Comedy
1
2 Jumanji (1995) Adventure|Children's|Fantasy
3 Grumpier Old Men (1995) Comedy|Romance
4 Waiting to Exhale (1995) Comedy|Drama
5 Father of the Bride Part II (1995) Comedy
6 Heat (1995) Action|Crime|Thriller
read_csv的nrows参数也很有用,如果数据文件很大,内存很小,读取数据不想全都读回,可以使用nrows函数指定读回的行数。
8.4 DataFrame存成csv
可以使用pandas的to_csv函数将DataFrame数据存储成csv文件。
import pandas as pd
df = pd.DataFrame({'name' : "hello the cruel world".split(),
'growth' : [100, 125, 150, 200]},
index = "jack tom mike nike".split())
print "*"* 10
print df
print "*"* 10
df.to_csv("out.csv", index_label = "index")
- index_lable参数,to_csv函数里的index_label参数是给出index或label列的名字。输出的out.csv文件如下:
index,growth,name
jack,100,hello
tom,125,the
mike,150,cruel
nike,200,world
程序执行结果:
**********
growth name
jack 100 hello
tom 125 the
mike 150 cruel
nike 200 world
**********
8.5 Excel文件创建DataFrame
pandas还可以从Excel文件提取数据创建DateFrame数据,但需要平台支持Excel文件的读写模块,可以安装xlrd或openpyxl模块。
$ sudo pip install xlrd
- read_excel函数读Excel里的数据,将上边jd.csv用excel打开,另存为jd.xls文件,然后用read_excel来读取Excel文件里的数据创建DataFrame。
import pandas as pd
df = pd.read_excel("jd.xls", index_col=0)
print df[:5]
- 可以使用to_excel函数将数据写入Excel文件。
import pandas as pd
idx = list("abcdef")
val1 = range(10, 16)
val2 = range(19, 25)
df1 = pd.DataFrame({"math": val1, "eng" : val2}, index = idx)
print df1
df2 = pd.DataFrame({"chn": val1, "phy" : val2}, index = idx)
print df2
writer = pd.ExcelWriter("record.xls")
df1.to_excel(writer, sheet_name = "me")
df2.to_excel(writer, sheet_name = "cp")
writer.save()
to_excel函数的形参sheet_name指定表单名。
- 读excel里多表单数据,创建DateFrame。上边代码将df1和df2数据写入Excel并生成record.xls文件,这个Excel文件里有两个表单:me和cp,现在用read_excel函数分别从两个表单里读取数据用于创建DataFrame。
import pandas as pd
df1 = pd.read_excel("record.xls", sheetname = "cp", index_col = 0)
print df1
print df1.index
df2 = pd.read_excel("record.xls", sheetname = "me", index_col = 0)
print df2
print df2.index
程序运行时结果:
chn phy
a 10 19
b 11 20
c 12 21
d 13 22
e 14 23
f 15 24
Index([u'a', u'b', u'c', u'd', u'e', u'f'], dtype='object')
eng math
a 19 10
b 20 11
c 21 12
d 22 13
e 23 14
f 24 15
Index([u'a', u'b', u'c', u'd', u'e', u'f'], dtype='object')
8.6 JSON数据创建DataFrame
pandas里提供to_json函数可以将DataFrame数据输出成json格式的数据文件。
import pandas as pd
df3 = pd.read_table("movies.dat", sep = "::",engine='python')
print df3
df3[:500].to_json("movies.json")
print "end"
程序执行完后,生成movies.json文件,可以用pandas的read_json函数将json文件里的数据读回并创建DataFrame数据。
import pandas as pd
df3 = pd.read_json("movies.json")
print df3