官方練習 Pandas 資料結構簡介 Series VS DataFrame
傳遞的索引是軸標籤列表。因此,根據資料的不同,這可分為幾種情況:
In [42]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
來自ndarray
如果data是ndarray,則索引的長度必須與資料的長度相同。如果沒有傳遞索引,將建立一個具有值的索引。[0, ..., len(data) - 1]
s = pd.Series(data, index=index) 在這裡,data可以有很多不同的東西:
一個Python字典
一個ndarray
標量值(如5)
傳遞的索引是軸標籤列表。
In [43]:
s = pd.Series(np.random.randn(5),index=['a', 'b', 'c', 'd', 'e'])
s
Out[43]:
a 0.752638
b 0.677576
c 0.070753
d -1.030516
e 0.030880
dtype: float64
In [44]:
s.index
Out[44]:
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
In [45]:
pd.Series(np.random.randn(5))
Out[45]:
0 -0.342847 1 0.595423 2 -0.287877 3 -0.742966 4 -0.738780 dtype: float64
從dict
注意 當資料是dict,並且未傳遞Series索引時,如果您使用的是Python版本> = 3.6且Pandas版本> = 0.23 ,則索引將按dict的插入順序排序。
如果您使用的是Python <3.6或Pandas <0.23,並且未傳遞Series索引,則索引將是詞彙順序的dict鍵列表。
In [89]:
d = {'b' : 1, 'a' : 0, 'c' : 2}
pd.Series(d).index
Out[89]:
Index(['a', 'b', 'c'], dtype='object')
In [87]:
d = {'a' : 0., 'b' : 1., 'c' : 2.} pd.Series(d)
Out[87]:
a 0.0
b 1.0
c 2.0
dtype: float64
如果傳遞索引,則將拉出與索引中的標籤對應的資料中的值。 空餘的為NaN
In [48]:
pd.Series(d,index=['b', 'c', 'd', 'a'])
Out[48]:
b 1.0
c 2.0
d NaN
a 0.0
dtype: float64
從標量值,如果data是標量值,則必須提供索引。將重複該值以匹配索引的長度。
In [49]:
pd.Series(5, index=['a', 'b', 'c', 'd', 'e'])
Out[49]:
a 5
b 5
c 5
d 5
e 5
dtype: int64
In [50]:
pd.Series([5.,3.,5.,3.,2], index=['a', 'b', 'c', 'd', 'e'])
Out[50]:
a 5.0
b 3.0
c 5.0
d 3.0
e 2.0
dtype: float64
Series行為與a非常相似ndarray,並且是大多數NumPy函式的有效引數。但是,切片等操作也會對索引進行切片。
In [51]:
s
Out[51]:
a 0.752638
b 0.677576
c 0.070753
d -1.030516
e 0.030880
dtype: float64
In [52]:
s[0]
Out[52]:
0.75263790197081093
In [53]:
s[:3]
Out[53]:
a 0.752638
b 0.677576
c 0.070753
dtype: float64
In [54]:
s[s>s.median()]
Out[54]:
a 0.752638
b 0.677576
dtype: float64
In [55]:
s[[4, 3, 1]]
Out[55]:
e 0.030880
d -1.030516
b 0.677576
dtype: float64
In [56]:
np.exp(s)
Out[56]:
a 2.122592
b 1.969099
c 1.073316
d 0.356823
e 1.031362
dtype: float64
Series類似於固定大小的dict,您可以通過索引標籤獲取和設定值
In [57]:
s['a']
Out[57]:
0.75263790197081093
In [58]:
s['e']
Out[58]:
0.030879785155672308
In [59]:
s
Out[59]:
a 0.752638
b 0.677576
c 0.070753
d -1.030516
e 0.030880
dtype: float64
In [61]:
'e' in s
Out[61]:
True
In [62]:
'f' in s
Out[62]:
False
In [64]:
# 如果未包含標籤,則會引發異常:
#s['f']
使用該get方法,缺少的標籤將返回None或指定的預設值:
In [65]:
s.get('f')
In [66]:
s.get('f', np.nan)
Out[66]:
nan
使用Series¶進行向量化操作和標籤對齊
使用原始NumPy陣列時,通常不需要迴圈使用value-by-value。
在pandas中使用Series時也是如此。系列也可以傳遞到大多數期待ndarray的NumPy方法。
In [72]:
s
Out[72]:
a 0.752638
b 0.677576
c 0.070753
d -1.030516
e 0.030880
dtype: float64
In [69]:
s+s
Out[69]:
a 1.505276
b 1.355152
c 0.141507
d -2.061032
e 0.061760
dtype: float64
In [70]:
s*2
Out[70]:
a 1.505276
b 1.355152
c 0.141507
d -2.061032
e 0.061760
dtype: float64
In [71]:
np.exp(s)
Out[71]:
a 2.122592
b 1.969099
c 1.073316
d 0.356823
e 1.031362
dtype: float64
Series和ndarray之間的主要區別在於Series之間的操作會根據標籤自動對齊資料。
因此,您可以在不考慮所涉及的系列是否具有相同標籤的情況下編寫計算。
In [77]:
s[1:]
Out[77]:
b 0.677576
c 0.070753
d -1.030516
e 0.030880
dtype: float64
In [78]:
s[:-1]
Out[78]:
a 0.752638
b 0.677576
c 0.070753
d -1.030516
dtype: float64
未對齊Series之間的操作結果將包含所涉及的索引的並集。
如果在一個系列或另一個系列中找不到標籤,則結果將標記為缺失NaN。
In [79]:
s[1:]+s[:-1]
Out[79]:
a NaN
b 1.355152
c 0.141507
d -2.061032
e NaN
dtype: float64
Series也可以有一個name屬性:
name在許多情況下,Series將自動分配,特別是在拍攝一維DataFrame時,如下所示。
In [84]:
s = pd.Series(np.random.randn(5), name='something')
s
Out[84]:
0 0.070190
1 2.264641
2 0.416647
3 -1.156442
4 -0.259729
Name: something, dtype: float64
In [85]:
s.name
Out[85]:
'something'
版本0.18.0中的新功能。
您可以使用該pandas.Series.rename()方法重新命名Series 。
In [86]:
s2 = s.rename("different")
s2
Out[86]:
0 0.070190
1 2.264641
2 0.416647
3 -1.156442
4 -0.259729
Name: different, dtype: float64
DataFrame是一個二維標記資料結構,具有可能不同型別的列。
您可以將其視為電子表格或SQL表,或Series物件的字典。
它通常是最常用的pandas物件。與Series類似,DataFrame接受許多不同型別的輸入:
1D ndarray,list,dicts或Series的Dict
二維numpy.ndarray
結構化或記錄 ndarray
一個 Series
另一個 DataFrame
除了資料,您還可以選擇傳遞索引(行標籤)和 列(列標籤)引數。
1、從Series或詞典的詞典
得到的指數將是工會的各種系列的指標。 如果有任何巢狀的dicts,這些將首先轉換為Series。
如果沒有傳遞列,則列將是dict鍵的有序列表。
In [96]:
d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c'])}
df = pd.DataFrame(d)
df
Out[96]:
one | |
---|---|
a | 1.0 |
b | 2.0 |
c | 3.0 |
In [97]:
d = {'one' : pd.Series([1., 2., 3.], index=['a', 'b', 'c']),
'two' : pd.Series([1., 2., 3., 4.], index=['a', 'b', 'c', 'd'])}
In [98]:
df = pd.DataFrame(d)
df
Out[98]:
one | two | |
---|---|---|
a | 1.0 | 1.0 |
b | 2.0 | 2.0 |
c | 3.0 | 3.0 |
d | NaN | 4.0 |
In [99]:
pd.DataFrame(d, index=['d', 'b', 'a'])
Out[99]:
one | two | |
---|---|---|
d | NaN | 4.0 |
b | 2.0 | 2.0 |
a | 1.0 | 1.0 |
In [100]:
pd.DataFrame(d, index=['d', 'b', 'a'],columns=['two','three'])
Out[100]:
two | three | |
---|---|---|
d | 4.0 | NaN |
b | 2.0 | NaN |
a | 1.0 | NaN |
通過訪問索引和列屬性,可以分別訪問行和列標籤 :
注意 當一組特定的列與資料的dict一起傳遞時,傳遞的列將覆蓋dict中的鍵。
In [102]:
df.index
Out[102]:
Index(['a', 'b', 'c', 'd'], dtype='object')
In [103]:
df.columns
Out[103]:
Index(['one', 'two'], dtype='object')
從ndarrays / lists的字典
ndarrays必須都是相同的長度。如果傳遞索引,則它必須明顯與陣列的長度相同。
如果沒有傳遞索引,結果將是range(n),n陣列長度在哪裡。
In [105]:
d = {'one' : [1., 2., 3., 4.],
'two' : [4., 3., 2., 1.]}
In [106]:
pd.DataFrame(d)
Out[106]:
one | two | |
---|---|---|
0 | 1.0 | 4.0 |
1 | 2.0 | 3.0 |
2 | 3.0 | 2.0 |
3 | 4.0 | 1.0 |
In [107]:
pd.DataFrame(d,index=['a', 'b', 'c', 'd'])
Out[107]:
one | two | |
---|---|---|
a | 1.0 | 4.0 |
b | 2.0 | 3.0 |
c | 3.0 | 2.0 |
d | 4.0 | 1.0 |
從結構化或記錄陣列
這種情況的處理方式與陣列的字典相同。
In [117]:
data = np.zeros((2,))
data
Out[117]:
array([ 0., 0.])
In [118]:
data = np.zeros((2,),dtype=[('A','i4'),('B', 'f4'),('C', 'a10')])
data
Out[118]:
array([(0, 0., b''), (0, 0., b'')],
dtype=[('A', '<i4'), ('B', '<f4'), ('C', 'S10')])
In [124]:
data = [(1,2,'Hello'),(2,3,'World')]
data
Out[124]:
[(1, 2, 'Hello'), (2, 3, 'World')]
In [120]:
pd.DataFrame(data)
Out[120]:
0 | 1 | 2 | |
---|---|---|---|
0 | 1 | 2 | Hello |
1 | 2 | 3 | World |
In [126]:
pd.DataFrame(data,index=['first','second'],columns=['C', 'A', 'B'])
Out[126]:
C | A | B | |
---|---|---|---|
first | 1 | 2 | Hello |
second | 2 | 3 | World |
In [125]:
pd.DataFrame(data, columns=['C', 'A', 'B'])
Out[125]:
C | A | B | |
---|---|---|---|
0 | 1 | 2 | Hello |
1 | 2 | 3 | World |
從dicts列表
In [129]:
data2 = [{'a': 1, 'b': 2}]
pd.Series(data2)
Out[129]:
0 {'a': 1, 'b': 2}
dtype: object
In [130]:
data2 = [{'a': 1, 'b': 2}]
pd.DataFrame(data2)
Out[130]:
a | b | |
---|---|---|
0 | 1 | 2 |
In [131]:
data2 = [{'a': 1, 'b': 2},
{'a': 5, 'b': 10, 'c': 20}]
pd.DataFrame(data2)
Out[131]:
a | b | c | |
---|---|---|---|
0 | 1 | 2 | NaN |
1 | 5 | 10 | 20.0 |
行標籤必須與行數相等,列標籤可以不等,也可以不存在,不存在了所在列全部補充NaN
In [134]:
pd.DataFrame(data2, index=['first', 'second'])
Out[134]:
a | b | c | |
---|---|---|---|
first | 1 | 2 | NaN |
second | 5 | 10 | 20.0 |
In [137]:
pd.DataFrame(data2, columns=['a', 'e'])
Out[137]:
a | e | |
---|---|---|
0 | 1 | NaN |
1 | 5 | NaN |
從元組的詞典,您可以通過傳遞元組字典自動建立多索引框架
In [139]:
pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2}})
Out[139]:
a | ||
---|---|---|
b | ||
A | B | 1 |
C | 2 |
In [138]:
pd.DataFrame({('a', 'b'): {('A', 'B'): 1, ('A', 'C'): 2},
('a', 'a'): {('A', 'C'): 3, ('A', 'B'): 4},
('a', 'c'): {('A', 'B'): 5, ('A', 'C'): 6},
('b', 'a'): {('A', 'C'): 7, ('A', 'B'): 8},
('b', 'b'): {('A', 'D'): 9, ('A', 'B'): 10}})
Out[138]:
a | b | |||||
---|---|---|---|---|---|---|
a | b | c | a | b | ||
A | B | 4.0 | 1.0 | 5.0 | 8.0 | 10.0 |
C | 3.0 | 2.0 | 6.0 | 7.0 | NaN | |
D | NaN | NaN | NaN | NaN | 9.0 |
從Series
結果將是一個與輸入Series具有相同索引的DataFrame,以及一個列,
其名稱是Series的原始名稱(僅當沒有提供其他列名時)。
日期時間
對於datetime64 [ns]型別,NaT表示缺少的值。這是一個偽本機標記值,可以由單個dtype(datetime64 [ns])中的NumPy表示。
pandas物件提供NaT和之間的互操作性NaN。