pandas使用與思考
最近工作中,有一個場景,是從快取中將資料讀取出來,再聚合。
當時想到了三種方案:
- 使用dict的方式累加
- 使用資料庫的臨時表進行資料聚合
- 使用pandas彙總
方式一、以前使用php寫過,考慮過不優雅,就放棄了
方式二、由於資料多,每次處理都要先寫入資料庫,然後再聚合,有點耗時,這方式也線上上測試了,
時間確實比較久。
所以採用了第三種方案:
我先貼出我的程式碼:
為了,剔除敏感資訊,我做了混淆和簡化
def sync_data_to_db():
"""
將快取中的資料聚合後,持久化到db
"""
today = datetime.datetime.now().strftime(`%Y-%m-%d`)
resp = data_api.get_data()
data_frame = pd.DataFrame([], columns=[`uid`, `age`, `country`])
for line in resp.iter_lines():
user = json.loads(line.decode(`utf-8`))
uid = user.get(`uid`)
age = user.get(`age`)
countries = user.get(`country`, [])
if countries:
for i in countries:
df = pd.DataFrame([[uid, age, country, i]], columns=[`uid`, `age`, `country`])
data_frame = data_frame.append(df)
else:
df = pd.DataFrame([[uid, age, country, `Unknow`]], columns=[`uid`, `age`, `country`])
data_frame = data_frame.append(df)
data_frame = data_frame.groupby([`age`, `country`])
.agg({`uid`: {`user_count`: len}})
UserCount.objects.filter(dt=today).delete()
for i in data_frame.iterrows():
age, country = i[0]
cnt = i[1].uid.user_count
user = UserCount.objects.filter(
dt=today,
age=age,
country=country
).first()
if user:
setattr(user, `cnt`, cnt)
else:
user = UserCount(
dt=today,
age=age,
country=country
cnt=cnt
)
user.save()
print(datetime.datetime.now())
下面開始介紹pandas的使用
Pandas介紹
pandas是一個提供快速、可擴充套件和展現資料結構的Python庫。目標是成為成為使用Python處理實踐和實際資料分析的模組。並且想成為任何語言都能使用的最強大的可擴充套件的資料操作與分析開源工具。
主要的特性如下:
- 為浮點數和與浮點數精度丟失提供了簡易的處理方法。
- 大資料(數字很大,不是通常意義的大資料)的處理。
- 自動而準確地處理資料佇列。
- 功能強大。
- 能方便地轉換不規則資料和差異資料。
- 智慧地處理大資料集的切片、子集。
- 智慧合併和連線資料集。
- 靈活地調整資料集。
- 從CSV、Excel和資料庫中匯入資料。
1、Python Data Analysis Library 或 pandas 是基於NumPy 的一種工具,該工具是為瞭解決資料分析任務而建立的。Pandas 納入了大量庫和一些標準的資料模型,提供了高效地操作大型資料集所需的工具。pandas提供了大量能使我們快速便捷地處理資料的函式和方法。你很快就會發現,它是使Python成為強大而高效的資料分析環境的重要因素之一。
2、Pandas 是python的一個資料分析包,最初由AQR Capital Management於2008年4月開發,並於2009年底開源出來,目前由專注於Python資料包開發的PyData開發team繼續開發和維護,屬於PyData專案的一部分。Pandas最初被作為金融資料分析工具而開發出來,因此,pandas為時間序列分析提供了很好的支援。 Pandas的名稱來自於皮膚資料(panel data)和python資料分析(data analysis)。panel data是經濟學中關於多維資料集的一個術語,在Pandas中也提供了panel的資料型別。
3、資料結構:
Series:一維陣列,與Numpy中的一維array類似。二者與Python基本的資料結構List也很相近,其區別是:List中的元素可以是不同的資料型別,而Array和Series中則只允許儲存相同的資料型別,這樣可以更有效的使用記憶體,提高運算效率。
Time- Series:以時間為索引的Series。
DataFrame:二維的表格型資料結構。很多功能與R中的data.frame類似。可以將DataFrame理解為Series的容器。以下的內容主要以DataFrame為主。
Panel :三維的陣列,可以理解為DataFrame的容器。
Pandas 有兩種自己獨有的基本資料結構。讀者應該注意的是,它固然有著兩種資料結構,因為它依然是 Python 的一個庫,所以,Python 中有的資料型別在這裡依然適用,也同樣還可以使用類自己定義資料型別。只不過,Pandas 裡面又定義了兩種資料型別:Series 和 DataFrame,它們讓資料操作更簡單了。
三、 Pandas使用
1、匯入pandas模組並使用別名,以及匯入Series模組,以下使用基於本次匯入。
In [1]: from pandas import Series
In [2]: import pandas as pd
2、Series
Series 就如同列表一樣,一系列資料,每個資料對應一個索引值。
Series 就是“豎起來”的 list:
In [3]: s = Series([1,2,3,4, "youdi", `king`, "world"])
In [4]: s
Out[4]:
0 1
1 2
2 3
3 4
4 youdi
5 king
6 world
dtype: object
另外一點也很像列表,就是裡面的元素的型別,由你任意決定(其實是由需要來決定)。
這裡,我們實質上建立了一個 Series 物件,這個物件當然就有其屬性和方法了。比如,下面的兩個屬性依次可以顯示 Series 物件的資料值和索引:
In [5]: s.index
Out[5]: RangeIndex(start=0, stop=7, step=1)
In [6]: s.values
Out[6]: array([1, 2, 3, 4, `youdi`, `king`, `world`], dtype=object)
列表的索引只能是從 0 開始的整數,Series 資料型別在預設情況下,其索引也是如此。不過,區別於列表的是,Series 可以自定義索引:
In [7]: s2 = Series(["youdi", 24, `man`], index=[`name`, `age`, `sex`])
In [8]: s2
Out[8]:
name youdi
age 24
sex man
dtype: object
每個元素都有了索引,就可以根據索引操作元素了。還記得 list 中的操作嗎?Series 中,也有類似的操作。先看簡單的,根據索引檢視其值和修改其值:
In [10]: s2.get(`name`)
Out[10]: `youdi`
In [11]: s2.get(`age`)
Out[11]: 24
In [12]: s2.get(`sex`)
Out[12]: `man`
In [13]: s2[`name`] = "liangchangyou"
In [14]: s2[`name`]
Out[14]: `liangchangyou`
In [15]: s2
Out[15]:
name liangchangyou
age 24
sex man
dtype: object
這是不是又有點類似 dict 資料了呢?的確如此。看下面就理解了。
讀者是否注意到,前面定義 Series 物件的時候,用的是列表,即 Series() 方法的引數中,第一個列表就是其資料值,如果需要定義 index,放在後面,依然是一個列表。除了這種方法之外,還可以用下面的方法定義 Series 物件:
In [16]: adobe = {"ps": 200, "ae": 300, `pr`: 400, "ai": 500}
In [17]: s_adobe = Series(adobe)
In [18]: s_adobe
Out[18]:
ae 300
ai 500
pr 400
ps 200
dtype: int64
現在是否理解為什麼前面那個類似 dict 了?因為本來就是可以這樣定義的。
這時候,索引依然可以自定義。Pandas 的優勢在這裡體現出來,如果自定義了索引,自定的索引會自動尋找原來的索引,如果一樣的,就取原來索引對應的值,這個可以簡稱為“自動對齊”。
In [19]: s_ph = Series(adobe, index=["ps", "ae", "pr", "ai"])
In [20]: s_ph
Out[20]:
ps 200
ae 300
pr 400
ai 500
dtype: int64
In [21]: s_ph = Series(adobe, index=["ps", "ae", "pr", "ai", "maya"])
In [22]:
In [22]: s_ph
Out[22]:
ps 200.0
ae 300.0
pr 400.0
ai 500.0
maya NaN
dtype: float64
在 Pandas 中,如果沒有值,都對齊賦給 NaN。
Pandas 有專門的方法來判斷值是否為空。
In [23]: pd.isnull(s_ph)
Out[23]:
ps False
ae False
pr False
ai False
maya True
dtype: bool
此外,Series 物件也有同樣的方法:
In [24]: s_ph.isnull()
Out[24]:
ps False
ae False
pr False
ai False
maya True
dtype: bool
其實,對索引的名字,是可以從新定義的:
In [25]: s_ph.index = [`python`, `php`, `c`, `golang`, `sql`]
In [26]: s_ph
Out[26]:
python 200.0
php 300.0
c 400.0
golang 500.0
sql NaN
dtype: float64
對於 Series 資料,也可以做類似下面的運算(關於運算,後面還要詳細介紹):
In [27]: s_ph * 3
Out[27]:
python 600.0
php 900.0
c 1200.0
golang 1500.0
sql NaN
dtype: float64
Series就先簡要寫到這,下面看pandas的另一種資料結構DataFrame.
DataFrame
DataFrame 是一種二維的資料結構,非常接近於電子表格或者類似 mysql 資料庫的形式。它的豎行稱之為 columns,橫行跟前面的 Series 一樣,稱之為 index,也就是說可以透過 columns 和 index 來確定一個主句的位置。
首先來匯入模組
In [28]: from pandas import Series,DataFrame
In [30]: names = [`youdi`, `rino`, `jackson`]
In [31]: age = [24, 35, 60]
In [32]: sex = [`man`, `women`, `man`]
In [33]: users = {"name": names, "age":age, "sex":sex}
In [34]: df = DataFrame(users)
In [35]: df
Out[35]:
age name sex
0 24 youdi man
1 35 rino women
2 60 jackson man
這是定義一個 DataFrame 物件的常用方法——使用 dict 定義。字典的“鍵”(”name”,”age”,”sex”)就是 DataFrame 的 columns 的值(名稱),字典中每個“鍵”的“值”是一個列表,它們就是那一豎列中的具體填充資料。上面的定義中沒有確定索引,所以,按照慣例(Series 中已經形成的慣例)就是從 0 開始的整數。從上面的結果中很明顯表示出來,這就是一個二維的資料結構(類似 excel 或者 mysql 中的檢視效果)。
上面的資料顯示中,columns 的順序沒有規定,就如同字典中鍵的順序一樣,但是在 DataFrame 中,columns 跟字典鍵相比,有一個明顯不同,就是其順序可以被規定,向下面這樣做:
In [38]: df_1 = DataFrame(users, columns=[`sex`, `name`, `age`])
In [39]: df_1
Out[39]:
sex name age
0 man youdi 24
1 women rino 35
2 man jackson 60
跟 Series 類似的,DataFrame 資料的索引也能夠自定義
In [36]: df_1 = DataFrame(users, columns=[`name`, `age`, `sex`], index=[`I`, `II`, `III`])
In [37]: df_1
Out[37]:
name age sex
I youdi 24 man
II rino 35 women
III jackson 60 man
定義 DataFrame 的方法,除了上面的之外,還可以使用“字典套字典”的方式。
In [40]: books = {`name`: {1:"python", 2:"golang" }, "price":{1:60, 2:100}}
In [41]: df_2 = DataFrame(books)
In [42]: df_2
Out[42]:
name price
1 python 60
2 golang 100
在字典中就規定好數列名稱(第一層鍵)和每橫行索引(第二層字典鍵)以及對應的資料(第二層字典值),也就是在字典中規定好了每個資料格子中的資料,沒有規定的都是空。
DataFrame 物件的 columns 屬性,能夠顯示素有的 columns 名稱。並且,還能用下面類似字典的方式,得到某豎列的全部內容(當然包含索引):
In [43]: books = {`name`: {1:"python", 2:"golang" }, "price":{1:60}}
In [44]: df_2 = DataFrame(books)
In [45]: df_2
Out[45]:
name price
1 python 60.0
2 golang NaN
In [46]: df_2 = DataFrame(books, index=[1,2,3])
In [47]: df_2
Out[47]:
name price
1 python 60.0
2 golang NaN
3 NaN NaN
DataFrame 物件的 columns 屬性,能夠顯示素有的 columns 名稱。並且,還能用下面類似字典的方式,得到某豎列的全部內容(當然包含索引):
In [48]: df_2.get("name")
Out[48]:
1 python
2 golang
3 NaN
Name: name, dtype: object
下面操作是給同一列賦值
In [54]: setattr(df_2, `name`, `python`)
In [55]: df_2
Out[55]:
name price
1 python 60.0
2 python NaN
3 python NaN
In [56]: df_2[`price`] = 100
In [58]: df_2
Out[58]:
name price
1 python 100
2 python 100
3 python 100
也可以單獨的賦值,除了能夠統一賦值之外,還能夠“點對點”新增數值,結合前面的 Series,既然 DataFrame 物件的每豎列都是一個 Series 物件,那麼可以先定義一個 Series 物件,然後把它放到 DataFrame 物件中。如下:
In [59]: df_1
Out[59]:
sex name age
0 man youdi 24
1 women rino 35
2 man jackson 60
還可以更精準的修改資料嗎?當然可以,完全仿照字典的操作:
In [59]: df_1
Out[59]:
sex name age
0 man youdi 24
1 women rino 35
2 man jackson 60
In [60]: df_1[`age`][1] = 34
In [61]: df_1
Out[61]:
sex name age
0 man youdi 24
1 women rino 34
2 man jackson 60
差不多簡單的介紹了,由於df很像sql,所以類似sql都可以處理,資料的聚合,分類等。
我前一段時間學習了numpy,pandas,matplotlib等一些資料處理的工具, 我當時也沒有想過後面會使用到,就是看看。
現在回頭看,有時候遇到問題,很多內容都忘記了, 不能及時的寫出程式碼,但是我可以找出解決的方案。對知識的廣度以及視野也會影響你的職業素養。
這件事,讓我想起一個關於讀書的討論:
讀書的意義是什麼?
這個問題,就好比——你吃的美食最終都會變成糟粕,那你為什麼還要吃呢?
書,和食物,不也很相似嗎?
一個,因為好吃。
另一個,它們精華的部分會變成營養被你身體吸收,保證我們的成長,是潛移默化的
讀書也是類似的,當時是看不出成效的, 量變達到一定時候,就會質變。
相關文章
- pandas使用
- 資料清洗與預處理:使用 Python Pandas 庫Python
- Pandas的使用技巧
- 使用phoenix踩的坑與設計思考
- (新手)使用pandas操作EXCELExcel
- Python Pandas的使用 !!!!!詳解Python
- OC觀察者模式之KVO的使用與思考模式
- Numpy與Pandas學習網站學習網站
- 貝殼使用者偏好挖掘的思考與實踐
- pandas的to_csv()使用方法
- 使用Pandas DataFrame輸出報告
- 使用pandas進行資料分析
- pandas中dataframe與dict相互轉換
- MMORPG的困局與思考
- 聊聊《思考,快與慢》
- Django | 訊號使用思考Django
- Python利用pandas處理資料與分析Python
- pandas | DataFrame中的排序與彙總方法排序
- 關於使用 Vue 實現 Context-Menu 的思考與總結VueContext
- vue與react元件的思考VueReact元件
- Pandas之:Pandas簡潔教程
- cookie與session的自己思考與解釋CookieSession
- [python][科學計算][pandas]使用指南Python
- pandas中如何使用合併append函式?APP函式
- Pandas
- pandas中loc、iloc與ix的用法比較
- pandas | 詳解DataFrame中的apply與applymap方法APP
- pandas的外部資料匯入與常用方法
- 【Python自動化Excel】Python與pandas字串操作PythonExcel字串
- 系統效能提升利刃 | 快取技術使用的實踐與思考快取
- Pandas - pandas.Series.pipe 函式函式
- Pandas進階貳 pandas基礎
- Android 元件化方案探索與思考Android元件化
- 出海休閒思考與沉澱
- 程式碼與質量的思考與隨筆
- 使用Pandas IO工具流式傳輸源資料
- Pandas Series
- pandas(四)