1 引言
Python padas是常用的数据处理和分析模块,有特别的数据结构DataFrame。创建一个对象:
import pandas as pd
data=[[1,2,3],[4,5,6]]
index=['a','b']#行号
columns=['c','d','e']#列号
df=pd.DataFrame(data,index=index,columns=columns)#生成一个数据框
2 常遇到的错误
read_csv是常用的读取CSV格式的文件,其返回值就是DataFrame。新手很容易犯错认为DataFrame和array及list相同,可以用[][]来去行列中单个数据及切片数据:
比如:
ServiceLogs,98706832行x14列,8.77 GB,交易日志数据,每个交易会话可以有多条交易,A ServiceCodes,286行×8列,20 KB,交易分类的字典表,B
df = pd.read_csv(path, header=None) # 不设置header=None,默认第一行为头,也就是列索引
print(df)
0 1 2 3 4
0 ServiceLogs 98706832行x14列 8.77 GB 交易日志数据,每个交易会话可以有多条交易 A
1 ServiceCodes 286行×8列 20 KB 交易分类的字典表 B
print(df[0][1])
ServiceCodes
可以看到输出第一行,第二列竟然是第二行第一列。那是因为DataFrame的取值根本与array及list不同,但是如果习惯这样操作可以将DataFrame转为array。这样结果如大家所预料。
arr_df = np.array(df)
print(arr_df)
print(arr_df[0][1])
[['ServiceLogs' '98706832\xe8\xa1\x8cx14\xe5\x88\x97' '8.77 GB'
'\xe4\xba\xa4\xe6\x98\x93\xe6\x97\xa5\xe5\xbf\x97\xe6\x95\xb0\xe6\x8d\xae\xef\xbc\x8c\xe6\xaf\x8f\xe4\xb8\xaa\xe4\xba\xa4\xe6\x98\x93\xe4\xbc\x9a\xe8\xaf\x9d\xe5\x8f\xaf\xe4\xbb\xa5\xe6\x9c\x89\xe5\xa4\x9a\xe6\x9d\xa1\xe4\xba\xa4\xe6\x98\x93'
'A']
['ServiceCodes' '286\xe8\xa1\x8c\xc3\x978\xe5\x88\x97' '20 KB'
'\xe4\xba\xa4\xe6\x98\x93\xe5\x88\x86\xe7\xb1\xbb\xe7\x9a\x84\xe5\xad\x97\xe5\x85\xb8\xe8\xa1\xa8'
'B']]
98706832行x14列
3 那原因是什么那?
原因主要是在DataFrame中直接用方括号取值是索引,也就是列索引,然后是行索引。比如:
df['a']#取a列
df[['a','b']]#取a、b列
而在未指定索引,比如指定names参数(列索引),index_col参数(行索引)及header=None。默认行列索引分别为0-(num-1),所以也就阴差阳错出现上述情况。下面我们可以测试当修改行列索引之后,是否可以继续按照错误方法调用?
df = pd.read_csv(path2, header=None, names=list('abcde'))
print(df)
print(df[0][1])
a b c d e
0 ServiceLogs 98706832行x14列 8.77 GB 交易日志数据,每个交易会话可以有多条交易 A
1 ServiceCodes 286行×8列 20 KB 交易分类的字典表 B
Traceback (most recent call last):
print(df[0][1])
...
KeyError: 0
也就是提示我们键(Key)错误,无0这个键,因为列索引,也就是键已经改成了a,b,c,d,e。对行也是如此。
用索引则可以输出:
print(df["a"][1])
ServiceCodes
下面测试行索引:首先介绍参数 index_col,该参数是指定某一列为行索引,指定时可以使用标签索引或数字索引。
df = pd.read_csv(path2, header=None, names=list('abcde'), index_col=4)
df = pd.read_csv(path2, header=None, names=list('abcde'), index_col='e')
print(df)
a b c d
e
A ServiceLogs 98706832行x14列 8.77 GB 交易日志数据,每个交易会话可以有多条交易
B ServiceCodes 286行×8列 20 KB 交易分类的字典表
对于列来说不同点就是,可以使用即使指定了标签,也可以使用标签或者数字进行索引。
print(df["a"][1])
print(df["a"]["B"])
ServiceCodes
ServiceCodes
4 如何查找DataFrame的数据?
对于很多人来说先 “列”,后 “行”的索引方法,是不舒服的,但是实际上DataFrame内置有很多函数来查找取值。
at——通过行标签索引行数据(单个)
iat——通过行号索引行数据 (单个)
loc——通过行标签索引行数据 (切片)
iloc——通过行号索引行数据 (切片)
ix——通过行标签或者行号索引行数据(基于loc和iloc 的混合) (切片)
同理,索引列数据也是如此!
at:
print(df.at["A", "a"])
ServiceLogs
print(df.at["A", 1])
raise ValueError("At based indexing on an non-integer "
ValueError: At based indexing on an non-integer index can only have non-integer indexers
提醒我们at函数必须要标签索引,必需是非整型的参数。
iat:
print(df.iat[0, 1])
98706832行x14列
print(df.iat[0, "b"])
raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers
提醒我们iat函数必须要行号索引,必需是整型的参数。
print(df.iat[0:1, 1])
raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers
print(df.iat[0, 0:1])
raise ValueError("iAt based indexing can only have integer "
ValueError: iAt based indexing can only have integer indexers
print(df.at["A", "a":"e"])
TypeError: unhashable type
print(df.at["A":"B", "a"])
TypeError: 'slice('A', 'B', None)' is an invalid key
不能使用切片代表。
iloc:
print(df.iloc[0, 1])
98706832行x14列
print(df.iloc[0, 1:2])
b 98706832行x14列
Name: A, dtype: object
支持单个数值和切片,切片操作输出行列标签和类型。
print(df.iloc["A", "b"])
print(df.iloc["A":"B", "b"])
ValueError: Location based indexing can only have [integer, integer slice (START point is INCLUDED, END point is EXCLUDED), listlike of integers, boolean array] types
基于位置的索引只能是整数及整数切片, 前一个数值包括,后一个数值不包括。
loc:
print(df.loc["A", "b"])
98706832行x14列
print(df.loc["A":"B", "b"])
e
A 98706832行x14列
B 286行×8列
Name: b, dtype: object
print(df.loc["A", "b":"e"])
b 98706832行x14列
c 8.77 GB
d 交易日志数据,每个交易会话可以有多条交易
Name: A, dtype: object
print(df.loc["A":"B", "b":"e"])
b c d
e
A 98706832行x14列 8.77 GB 交易日志数据,每个交易会话可以有多条交易
B 286行×8列 20 KB 交易分类的字典表
注意:标签的索引是包括开头和结尾的标签。同样给出行列标签和类型。以切片方向为主。
但不能用行号索引:
print(df.loc[0, 1])
TypeError: cannot do label indexing on
with these indexers [0] of
print(df.loc[0, 1:2])
TypeError: cannot do label indexing on
with these indexers [0] of
ix:可以实现上述所有操作。
print(df.ix[0, 1])
98706832行x14列
print(df.ix[0, 0:2])
a ServiceLogs
b 98706832行x14列
Name: A, dtype: object
print(df.ix["A", "b"])
98706832行x14列
print(df.ix["A":"B", "b"])
e
A 98706832行x14列
B 286行×8列
Name: b, dtype: object
at及iat必须要具体位置,不能输出一行或一列。其他操作可以直接输出一行或一列。 方括号嵌套方括号是选值 。
df['a']#取a列
df[['a','b']]#取a、b列
#ix可以用数字索引,也可以用index和column索引
row0 = df.ix[0]#取第0行
row1 = df.ix[0:1]#取第0行
# print(row1)
a = df.ix['one':'two']#取one、two行
# print(a)
b = df.ix[0:2,0]#取第0、1行,第0列
# print(b)
c = df.ix[0:1,'a']#取第0行,a列
print(c)
d = df.ix[0:2,'a':'c']#取第0、1行,abc列
print(d)
c = df.ix['one':'two','a':'c']#取one、two行,abc列
# print(c)
d = df.ix[0:2,0:1]#取第0、1行,第0列
# print(d)
e = df.ix[0:2,0:2]#取第0、1行,第0、1列
# print(e)
#loc只能通过index和columns来取,不能用数字
f = df.loc['one','a']#one行,a列
print(f)
df.loc['one':'two','a']#one到two行,a列
df.loc['one':'two','a':'c']#one到two行,a到c列
df.loc['one':'two',['a','c']]#one到two行,ac列
#iloc只能用数字索引,不能用索引名
g = df.iloc[1:2]#前2行
print(g)
df.iloc[0]#第0行
df.iloc[0:2,0:2]#0、1行,0、1列
df.iloc[[0,2],[1,2,3]]#第0、2行,1、2、3列
#iat取某个单值,只能数字索引
df.iat[1,1]#第1行,1列
#at取某个单值,只能index和columns索引
df.at['one','a']#one行,a列
c d e
a 1 2 3
b 4 5 6
print df.loc['a']
print df.ix['a']
c 1
d 2
e 3
Name: a, dtype: int64
print df.iloc[1]
print df.ix[1]
c 4
d 5
e 6
Name: b, dtype: int64
print df.at['a']
return self.obj.get_value(*key, takeable=self._takeable)
TypeError: get_value() takes at least 3 arguments (3 given)
print df.iat[1]
return self.obj.get_value(*key, takeable=self._takeable)
TypeError: get_value() takes at least 3 arguments (3 given)
其中取多列可以用print df.ix[:,0:2]。