Python学习系列之padas-DataFrame

系统 3422 0

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]。


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论