Python學習系列之padas-DataFrame

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 <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <type 'int'>

print(df.loc[0, 1:2])

TypeError: cannot do label indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <type 'int'>

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章