目录
2.2.2 使用 pandas.DataFrame.from_dict 函数
2.2.3 使用pandas.DataFrame.from_records 函数
2.2.4 从 csv、Excel、txt、mysql 等等处获得数据并构造成 pandas.
Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理我们目前绝大多数应用领域里的典型用例。
1. Series
1.1 Series 定义
Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。
1.2 Series 构造
先说函数 pandas.Series( data, index, dtype, name, copy)
参数说明:
data:一组数据(ndarray 类型),元组、列表、字典、数组等都可以
index:数据索引标签,如果不指定,默认从 0 开始;如果指定的话,使用列表或者元组格式
进行指定,其中列表或者元组的长度需要和 data的数据行数一致。此处索引指的是
行索引。
dtype:数据类型,默认会自己判断。
name:设置名称。# 也可以不设置
copy:拷贝数据,默认为 False。
大家先看看例子
import numpy as np
import pandas as pd
a_dict={"a":"aa","b":"bb","c":"cc"}
b_list=list(range(10))
c_array=np.array(b_list)
print("*"*20+" Series from dict "+"*"*20)
a_serise=pd.Series(a_dict)
print(a_serise)
print(a_serise.index)
print(a_serise.dtype)
print(a_serise.dtypes)
print(a_serise.name)
print("*"*20+" Series from list "+"*"*20)
b_serise=pd.Series(b_list)
print(b_serise)
print(b_serise.index)
print(b_serise.dtype)
print(b_serise.name)
print("*"*20+" Series from array "+"*"*20)
c_serise=pd.Series(c_array,index=["001","002","003","004","005","006","007","008","009","010"],name="from array")
print(c_serise)
print(c_serise.index)
print(c_serise.dtype)
print(c_serise.dtypes)
print(c_serise.name)
print("*"*40)
运行结果是
******************** Series from dict ******************** a aa b bb c cc dtype: object Index(['a', 'b', 'c'], dtype='object') object object None ******************** Series from list ******************** 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 dtype: int64 RangeIndex(start=0, stop=10, step=1) int64 None ******************** Series from array ******************** 001 0 002 1 003 2 004 3 005 4 006 5 007 6 008 7 009 8 010 9 Name: from array, dtype: int32 Index(['001', '002', '003', '004', '005', '006', '007', '008', '009', '010'], dtype='object') int32 int32 from array ****************************************
2. DataFrame
2.1 DataFrame 定义
DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。
2.2 DataFrame 构造
2.2.1 使用 pandas.DataFrame 函数
DataFrame 构造方法:pandas.DataFrame( data, index, columns, dtype, copy)
参数说明:
data:一组数据(ndarray、series, map, lists, dict 等类型)。
index:索引值,或者可以称为行标签。
columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。
dtype:数据类型。
copy:拷贝数据,默认为 False。
1)对列表的转换和构造
先看看例子
data_list = [['Google',1],['Baidu',2],['Facebook',3]]
print("*"*20+" Dataframe from list"+"*"*20)
df1 = pd.DataFrame(data_list,dtype=float)
print(df1)
df1 = pd.DataFrame(data_list,index=["index1","index2","index3"],columns=['Company','Rank'],dtype=int)
print("*"*5+" Dataframe from list ,converte with index and columns "+"*"*5)
print(df1)
******************** Dataframe from list ******************** 0 1 0 Google 1.0 1 Baidu 2.0 2 Facebook 3.0 ***** Dataframe from list ,converte with index and columns ***** Company Rank index1 Google 1 index2 Baidu 2 index3 Facebook 3
运行结果如下,可以看出:
1) 对列表转换时候,每个子 list 就是一行数据,数值数据类别由 dtype 决定,如果dtype没
有指定,则沿用默认的 int 类型。
2)index 如果没有指定,则默认为 0,1,2......;columns如果没有指定,也是默认为 0,1,2......
3)和 Numpy 模块不一样,这里的数据类型不需要完全统一。
4) 对列表转换时候,是没有 columns 的名字的,它只有数据,所以加上 columns 参数很有必要,但是对于列表内部是字典的结构来说,columns 参数可能会带来意想不到的结果。
data_list = [['Google',1,"def"],['Baidu',2,"DFG"],['Facebook',3,"fgf"]]
print("*"*20+" Dataframe from list"+"*"*20)
df1 = pd.DataFrame(data_list)
print(df1)
df1 = pd.DataFrame(data_list,index=["index1","index2","index3"],columns=['Company','Rank',"Comments"],dtype=float)
print("*"*20+" Dataframe from list ,converte with index and columns "+"*"*20)
print(df1)
运行结果
******************** Dataframe from list ******************** 0 1 2 0 Google 1 def 1 Baidu 2 DFG 2 Facebook 3 fgf ******************** Dataframe from list ,converte with index and columns ******************** Company Rank Comments index1 Google 1.0 def index2 Baidu 2.0 DFG index3 Facebook 3.0 fgf
2)data 大结构是列表,小结构是字典的情况
这时候字典的 key 就是 column。在每个字典里面,每个Key-Value 对里面的Key,都是
column 名字。如果有些 Value 没有指定,会用默认 NaN。
如果pd.DataFrame里面指定了column,就会发现数据消失了!!!(其实是数据都变成了
NaN,Oh My God,发生什么事情了?)
index 如果没有指定,则默认为 0,1,2......
这时候是面向行进行转换和构造的。
data_dict = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20},{'a': 9, 'b': 22, 'c': 30}]
df = pd.DataFrame(data_dict)
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
print("*"*20+" Dataframe from dict "+"*"*20)
df = pd.DataFrame(data_dict,index=["index1","index2","index3"],dtype=float)
print(df)
print("*"*20+" Dataframe from dict "+"*"*20)
# 很可怕,这种情况下,数据好像消失了
df = pd.DataFrame(data_dict,index=["index1","index2","index3"],columns=["Company1","Company2","Company3","Company4"])
print(df)
# 试试看,如果是这么指定 columns呢
print("*"*20+" Dataframe from dict "+"*"*20)
df = pd.DataFrame(data_dict,index=["index1","index2","index3"],columns=["a","b","Company3","Company4"])
print(df)
******************** Dataframe from dict ******************** a b c 0 1 2 NaN 1 5 10 20.0 2 9 22 30.0 ******************** Dataframe from dict ******************** a b c index1 1.0 2.0 NaN index2 5.0 10.0 20.0 index3 9.0 22.0 30.0 ******************** Dataframe from dict ******************** Company1 Company2 Company3 Company4 index1 NaN NaN NaN NaN index2 NaN NaN NaN NaN index3 NaN NaN NaN NaN ******************** Dataframe from dict ******************** a b Company3 Company4 index1 1 2 NaN NaN index2 5 10 NaN NaN index3 9 22 NaN NaN
让我们想象一下,当使用 columns=["Company1","Company2","Company3","Company4"] 时候到底发生什么了 ,为什么使用 columns=["a","b","Company3","Company4"] 时候,部分数据又出现了。
a) 前面我们强调过,这时候是面向行进行转换和构造的。列表中每一个子结构(可以是列表,也可以是字典),都是一行数据;
b)但是当子结构是列表时候,它就是单纯的数据,如果 pd.DataFrame函数不给它赋予 index 和 columns 参数时候,会看得更清晰一点。
c) 当子结构是字典时候,Key 就是 column 名字,而 value 则是一行数据。如果没有指定 columns参数,所有的 key 组合起来,就形成了 columns;但是一旦指定 columns 参数,那就是另外一个问题了。如果有和现有 Key 名字相同的 column,那很好,大家殊路同归,那如果 columns 里面没有和 Key 一样的名字呢,那没办法,只能按照 columns 参数来,认为是 NaN,也就是将 columns 里面没有提及的字典数据,给清洗掉了。
这种清洗方法非常强大,多试试就会爱上的。
3)对字典 dict 的转换和构造
代码如下
data = {'Animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
'Age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
'Visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
'Priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
indexs = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data)
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
df = pd.DataFrame(data,index=indexs)
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
# 使用 exclude 指定某些列的名, 可以清洗掉这些列的数据
df = pd.DataFrame(data,index=indexs,columns=["Animal","Visits"])
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
运行结果
******************** Dataframe from dict ******************** Animal Age Visits Priority 0 cat 2.5 1 yes 1 cat 3.0 3 yes 2 snake 0.5 2 no 3 dog NaN 3 yes 4 dog 5.0 2 no 5 cat 2.0 3 no 6 snake 4.5 1 no 7 cat NaN 1 yes 8 dog 7.0 2 no 9 dog 3.0 1 no ******************** Dataframe from dict ******************** Animal Age Visits Priority a cat 2.5 1 yes b cat 3.0 3 yes c snake 0.5 2 no d dog NaN 3 yes e dog 5.0 2 no f cat 2.0 3 no g snake 4.5 1 no h cat NaN 1 yes i dog 7.0 2 no j dog 3.0 1 no ******************** Dataframe from dict ******************** Animal Visits a cat 1 b cat 3 c snake 2 d dog 3 e dog 2 f cat 3 g snake 1 h cat 1 i dog 2 j dog 1
2.2.2 使用 pandas.DataFrame.from_dict 函数
语法格式 pandas.DataFrame.from_dict( data, columns, dtype)
参数说明:
data:字典或类似数组的对象来创建DataFrame。
orient: 数据的方向。 允许值为(“列”("columns"),“索引”("index")),默认值为“列”。
columns: 当方向为“索引”时,用作DataFrame标签的值的列表。 如果与列方向一起使用,则
会引发 ValueError
。
请注意,这里没有 index 参数,标准的python字典不保留其键的顺序,index 无用武之地。
1) data 是字典的情况,面向列进行转换
sales = {'account': ['Jones LLC', 'Alpha Co', 'Blue Inc'],
'Jan': [100, 200, 300],
'Feb': [200, 400, 600],
'Mar': [150, 300, 450]}
df = pd.DataFrame.from_dict(sales,dtype=float)
print(df)
print("*"*20+" Dataframe from dict "+"*"*20)
df = pd.DataFrame.from_dict(sales,columns=["Company1","Company2","Company3","Company4"])
运行结果可以,看到当 orient 为默认的列时候, 使用了 colums 参数,触发了 ValueError
account Jan Feb Mar 0 Jones LLC 100.0 200.0 150.0 1 Alpha Co 200.0 400.0 300.0 2 Blue Inc 300.0 600.0 450.0 ******************** Dataframe from dict ********************--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-64-3b7eb4740328> in <module> 6 print(df) 7 print("*"*20+" Dataframe from dict "+"*"*20) ----> 8 df = pd.DataFrame.from_dict(sales,columns=["Company1","Company2","Company3","Company4"]) ~\Anaconda3\lib\site-packages\pandas\core\frame.py in from_dict(cls, data, orient, dtype, columns) 1367 elif orient == "columns": 1368 if columns is not None: -> 1369 raise ValueError("cannot use columns parameter with orient='columns'") 1370 else: # pragma: no cover 1371 raise ValueError("only recognize index or columns for orient") ValueError: cannot use columns parameter with orient='columns'
当 orient 为行时候 ,即 orient ="index"
sales = {'account': ['Jones LLC', 'Alpha Co', 'Blue Inc'],
'Jan': [100, 200, 300],
'Feb': [200, 400, 600],
'Mar': [150, 300, 450]}
df = pd.DataFrame.from_dict(sales)
print(df)
print("*"*20+" Dataframe from dict "+"*"*20)
df = pd.DataFrame.from_dict(sales,orient="columns",dtype=float)
print(df)
print("*"*20+" Dataframe from dict "+"*"*20)
df = pd.DataFrame.from_dict(sales,orient="index",columns=["Company1","Company2","Company3"])
print(df)
运行结果是
account Jan Feb Mar 0 Jones LLC 100 200 150 1 Alpha Co 200 400 300 2 Blue Inc 300 600 450 ******************** Dataframe from dict ******************** account Jan Feb Mar 0 Jones LLC 100.0 200.0 150.0 1 Alpha Co 200.0 400.0 300.0 2 Blue Inc 300.0 600.0 450.0 ******************** Dataframe from dict ******************** Company1 Company2 Company3 account Jones LLC Alpha Co Blue Inc Jan 100 200 300 Feb 200 400 600 Mar 150 300 450
2.2.3 使用pandas.DataFrame.from_records 函数
使用pandas进行面向行的方法 from_records 。此方法类似于字典方法,但需要显式调出列标签。
pandas.DataFrame.from_records(data,index = None,exclude = None,columns = None,coerce_float = False,nrows = None )
参数说明:
data : ndarray
(结构化dtype
),元组列表,dict
或 DataFrame
index : 字符串,字段列表,类似数组,用作索引的数组字段,交替使用的一组特定输入标签
exclude : 序列(sequence),默认None
,要排除的列或字段
columns : 序列(sequence),默认None
,要使用的列名称。如果传递的数据没有与之关联的
名称,则此参数提供列的名称。否则,此参数指示结果中列的顺序
(数据中未找到的任何名称将变为全NaN列)
coerce_float : boolean
,默认为False
,尝试将非字符串,非数字对象(如
decimal.Decimal
)的值转换为浮点。对SQL
结果集很有用
nrows : int
,默认None
,如果数据是迭代器(iterator),则读取的行数
1) 对元组的转换和构造
sales = [('Jones LLC', 150, 200, 50),
('Alpha Co', 200, 210, 90),
('Blue Inc', 140, 215, 95)]
labels = ['account', 'Jan', 'Feb', 'Mar']
df = pd.DataFrame.from_records(sales, columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
df = pd.DataFrame.from_records(sales, index=["a","b","c"],columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
df = pd.DataFrame.from_records(sales, index=["a","b","c"],exclude=["account"],columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
运行结果是
******************** Dataframe from tuple ******************** account Jan Feb Mar 0 Jones LLC 150 200 50 1 Alpha Co 200 210 90 2 Blue Inc 140 215 95 ******************** Dataframe from tuple ******************** account Jan Feb Mar a Jones LLC 150 200 50 b Alpha Co 200 210 90 c Blue Inc 140 215 95 ******************** Dataframe from tuple ******************** Jan Feb Mar a 150 200 50 b 200 210 90 c 140 215 95
2) 对列表的转换和构造,和元组的结构一模一样,有兴趣的同学可以想想为什么
sales = [['Jones LLC', 150, 200, 50],
['Alpha Co', 200, 210, 90],
['Blue Inc', 140, 215, 95]]
labels = ['account', 'Jan', 'Feb', 'Mar']
df = pd.DataFrame.from_records(sales, columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
df = pd.DataFrame.from_records(sales, index=["a","b","c"],columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
df = pd.DataFrame.from_records(sales, index=["a","b","c"],exclude=["account"],columns=labels)
print("*"*20+" Dataframe from tuple "+"*"*20)
print(df)
运行结果
******************** Dataframe from tuple ******************** account Jan Feb Mar 0 Jones LLC 150 200 50 1 Alpha Co 200 210 90 2 Blue Inc 140 215 95 ******************** Dataframe from tuple ******************** account Jan Feb Mar a Jones LLC 150 200 50 b Alpha Co 200 210 90 c Blue Inc 140 215 95 ******************** Dataframe from tuple ******************** Jan Feb Mar a 150 200 50 b 200 210 90 c 140 215 95
3) 对 ndarray 进行操作
上代码
import numpy as np
import pandas as pd
arr1 = np.array([[1,3,5,7],
[2,4,6,8],
[11,13,15,17],
[12,14,16,18],
[100,101,102,103]])
# 二维数组的打印结果
print(arr1,'\n')
labels=["column1","column2","column3","column4"]
df = pd.DataFrame.from_records(arr1, index=["a","b","c","d","e"],exclude=["column3"],columns=labels)
print("*"*20+" Dataframe from ndarray "+"*"*20)
print(df)
运行结果
[[ 1 3 5 7] [ 2 4 6 8] [ 11 13 15 17] [ 12 14 16 18] [100 101 102 103]] ******************** Dataframe from ndarray ******************** column1 column2 column4 a 1 3 7 b 2 4 8 c 11 13 17 d 12 14 18 e 100 101 103
4)对 字典进行操作
代码如下
data = {'Animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
'Age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
'Visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
'Priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
indexs = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame.from_records(data)
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
df = pd.DataFrame.from_records(data,index=indexs)
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
# 使用 exclude 指定某些列的名, 可以清洗掉这些列的数据
df = pd.DataFrame.from_records(data,index=indexs,exclude=["Age"])
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
# 使用 columns 指定某些列的名, 可以清洗掉除了这些列以外的数据
df = pd.DataFrame.from_records(data,index=indexs,columns=["Animal","Visits"])
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
# columns 名字如果不存在,则会出错
df = pd.DataFrame.from_records(data,index=indexs,columns=["Animal2","Visits3"])
print("*"*20+" Dataframe from dict "+"*"*20)
print(df)
运行结果
******************** Dataframe from dict ******************** Age Animal Priority Visits 0 2.5 cat yes 1 1 3.0 cat yes 3 2 0.5 snake no 2 3 NaN dog yes 3 4 5.0 dog no 2 5 2.0 cat no 3 6 4.5 snake no 1 7 NaN cat yes 1 8 7.0 dog no 2 9 3.0 dog no 1 ******************** Dataframe from dict ******************** Age Animal Priority Visits a 2.5 cat yes 1 b 3.0 cat yes 3 c 0.5 snake no 2 d NaN dog yes 3 e 5.0 dog no 2 f 2.0 cat no 3 g 4.5 snake no 1 h NaN cat yes 1 i 7.0 dog no 2 j 3.0 dog no 1 ******************** Dataframe from dict ******************** Animal Priority Visits a cat yes 1 b cat yes 3 c snake no 2 d dog yes 3 e dog no 2 f cat no 3 g snake no 1 h cat yes 1 i dog no 2 j dog no 1 ******************** Dataframe from dict ******************** Animal Visits a cat 1 b cat 3 c snake 2 d dog 3 e dog 2 f cat 3 g snake 1 h cat 1 i dog 2 j dog 1--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-38-14778bca4e42> in <module> 22 print(df) 23 ---> 24 df = pd.DataFrame.from_records(data,index=indexs,columns=["Animal2","Visits3"]) 25 print("*"*20+" Dataframe from dict "+"*"*20) 26 print(df) ~\Anaconda3\lib\site-packages\pandas\core\frame.py in from_records(cls, data, index, exclude, columns, coerce_float, nrows) 1877 else: 1878 try: -> 1879 index_data = [arrays[arr_columns.get_loc(field)] for field in index] 1880 except (KeyError, TypeError): 1881 # raised by get_loc, see GH#29258 ~\Anaconda3\lib\site-packages\pandas\core\frame.py in <listcomp>(.0) 1877 else: 1878 try: -> 1879 index_data = [arrays[arr_columns.get_loc(field)] for field in index] 1880 except (KeyError, TypeError): 1881 # raised by get_loc, see GH#29258 AttributeError: 'list' object has no attribute 'get_loc'
2.2.4 从 csv、Excel、txt、mysql 等等处获得数据并构造成 pandas.
篇幅较多,会在后续慢慢讲。
'''
要是大家觉得写得还行,麻烦点个赞或者收藏吧,想给博客涨涨人气,非常感谢!
'''