Pandas
最近在學AI,但所謂AI其實更多時間是在處理資料。這邊紀錄一下pandas的使用過程,因為不想看完整本說明書,就碰到甚麼問題就找甚麼解方。
先科普一下,pandas有分兩種數據結構,一個是Series一個是DataFrame,以python來類比分別對應到list和dict。但DataFrame更加強大,除了行索引(index)之外也可以做出列索引(columns)。
初始化
dates = pd.date_range('20160101',periods=6)
df = pd.DataFrame(np.random.randn(6,4),
index=dates,
columns=['a','b','c','d'])
a b c d
2016-01-01 -0.243433 -0.809199 -0.532605 0.687522
2016-01-02 0.274463 1.086829 0.492148 0.397501
2016-01-03 -0.858649 -0.558727 -0.872328 -1.430168
2016-01-04 0.976597 -1.436458 -1.341834 -0.263957
2016-01-05 1.008789 -0.286005 2.340308 0.567542
2016-01-06 -0.171215 -0.349031 -1.650479 -0.564692
取值
Pandas取值是以列索引為主,以上面的例子來說,只能依照abcd來拿資料,[x]
形式或.x
形式皆可。
df['a']
df.a
2016-01-01 -0.243433
2016-01-02 0.274463
2016-01-03 -0.858649
2016-01-04 0.976597
2016-01-05 1.008789
2016-01-06 -0.171215
Freq: D, Name: a, dtype: float64
但是透過loc
也可以指定行列取得特定目標。
df.loc['2016-01-04', 'b']
-1.436457692060179
或者取得特定行。
df.loc['2016-01-01']
a -0.243433
b -0.809199
c -0.532605
d 0.687522
Name: 2016-01-01 00:00:00, dtype: float64
filter
可以根據列索引來篩選,例如大小於或等於。
df[df.a > 0]
a b c d
2016-01-02 0.274463 1.086829 0.492148 0.397501
2016-01-04 0.976597 -1.436458 -1.341834 -0.263957
2016-01-05 1.008789 -0.286005 2.340308 0.567542
也可以多重條件,但有兩點要注意,and和or使用的是位元運算子(&, |)且要括號。
df[(df.a > 0) & (df.d > 0)]
a b c d
2016-01-02 0.274463 1.086829 0.492148 0.397501
2016-01-05 1.008789 -0.286005 2.340308 0.567542
賦值
賦值其實就是取值的相反,但有一些特殊之處,例如一次塞一列。
df['e'] = pd.Series([1,2,3,4,5,6], index=pd.date_range('20160101',periods=6))
a b c d e
2016-01-01 -0.243433 -0.809199 -0.532605 0.687522 1
2016-01-02 0.274463 1.086829 0.492148 0.397501 2
2016-01-03 -0.858649 -0.558727 -0.872328 -1.430168 3
2016-01-04 0.976597 -1.436458 -1.341834 -0.263957 4
2016-01-05 1.008789 -0.286005 2.340308 0.567542 5
2016-01-06 -0.171215 -0.349031 -1.650479 -0.564692 6
一次塞一行也是可行的,因為DataFrame可以對沒有index的行賦值。
df.loc['test'] = [1,2,3,4]
a b c d
2016-01-01 00:00:00 -0.243433 -0.809199 -0.532605 0.687522
2016-01-02 00:00:00 0.274463 1.086829 0.492148 0.397501
2016-01-03 00:00:00 -0.858649 -0.558727 -0.872328 -1.430168
2016-01-04 00:00:00 0.976597 -1.436458 -1.341834 -0.263957
2016-01-05 00:00:00 1.008789 -0.286005 2.340308 0.567542
2016-01-06 00:00:00 -0.171215 -0.349031 -1.650479 -0.564692
test 1.000000 2.000000 3.000000 4.000000
雖然格式有點跑掉,但是是可行的。其實還有另外一種更快速的作法,但僅限沒有指定index的情況。以下例子以Series作為append的對象,並且指定columns對應的值,而且還要設定參數ignore_index=True
。
df = df.append(pd.Series({'a':1, 'b':2, 'c':3, 'd':4}), ignore_index=True)
a b c d
0 -0.243433 -0.809199 -0.532605 0.687522
1 0.274463 1.086829 0.492148 0.397501
2 -0.858649 -0.558727 -0.872328 -1.430168
3 0.976597 -1.436458 -1.341834 -0.263957
4 1.008789 -0.286005 2.340308 0.567542
5 -0.171215 -0.349031 -1.650479 -0.564692
6 1.000000 2.000000 3.000000 4.000000
有兩個重點要注意:
- index消失,變成單純數列
- append是mutable API,所以要把結果重新塞回變數內