(本文大部分內容源自實驗樓“Pandas百題大沖關”)
- 實驗環(huán)境為Jupyter Notebook
- 最好自己動手敲一遍代碼
大多是基礎知識,有些小技巧還是挺有用的贝奇,不熟悉的話一定要自己敲一遍代碼熟悉一下。
涉及的主要知識點有:
- 創(chuàng)建 Series
- Series 基本操作
- 創(chuàng)建 DataFrame
- DataFrame 基本操作
- DataFrame 文件操作
- Series睡雇,DataFrame 和多索引
- 透視表
- 數據清洗
- 數據預處理
- 可視化
基礎部分
1. 導入Pandas
import pandas as pd
2. 查看Pandas版本信息
print(pd.__version__)
創(chuàng)建Series數據類型
3. 從列表創(chuàng)建Series
arr = [0, 1, 2, 3, 4]
s1 = pd.Series(arr) # 如果不指定索引萌衬,則默認從 0 開始
s1
# 可以直接pd.Series([0,1,2,3,4])
4. 從ndarray創(chuàng)建Series
import numpy as np
n = np.random.randn(5) # 創(chuàng)建一個隨機 Ndarray 數組
index = ['a', 'b', 'c', 'd', 'e']
s2 = pd.Series(n, index=index)
s2
# 也可s2 = pd.Series(np.random.randn(5),index=list('abcde'))
5. 從字典創(chuàng)建Series
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
s3 = pd.Series(d)
s3
Series基本操作
6. 修改Series索引
print(s1) # 以 s1 為例
s1.index = ['A', 'B', 'C', 'D', 'E'] # 修改后的索引
s1
7. Series縱向拼接
s4 = s3.append(s1) # 將 s1 拼接到 s3
s4
8. Series按指定索引刪除元素
print(s4)
s4 = s4.drop('e') # 刪除索引為 e 的值
s4
9. Series修改指定索引元素
s4['A'] = 6 # 修改索引為 A 的值 = 6
s4
10. Seires按指定索引查找元素
s4['B']
11. Series切片操作
# 例如對s4的前3個元素訪問
s4[:3]
Series運算
12 - 15. Series加法、減法它抱、乘法奄薇、除法運算
Series 的加減乘除運算是按照索引計算,如果索引不同則填充為 NaN
(空值)抗愁。
# 加法
s4.add(s3)
# 減法
s4.sub(s3)
# 乘法
s4.mul(s3)
# 除法
s4.div(s3)
16 -19. Series求中位數、求和呵晚、求最小值蜘腌、求最大值
# 求中位數
s4.median()
# 求和
s4.sum()
# 求最小值
s4.min()
# 求最大值
s4.max()
創(chuàng)建DataFrame數據類型
20. 通過numpy數組創(chuàng)建DataFrame
dates = pd.date_range('today', periods=6) # 定義時間序列作為 index
num_arr = np.random.randn(6, 4) # 傳入 numpy 隨機數組
columns = ['A', 'B', 'C', 'D'] # 將列表作為列名
df1 = pd.DataFrame(num_arr, index=dates, columns=columns)
df1
21. 通過字典數組創(chuàng)建DataFrame
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df2 = pd.DataFrame(data, index=labels)
df2
使用字典創(chuàng)建DataFrame時,字典的鍵作為DataFrame的列名饵隙。
22. 查看DataFrame的數據類型
df2.dtypes
DataFrame的基本操作
23. 預覽DataFrame的前五行
df2.head()
24. 查看DataFrame的后三行數據
df2.tail(3)
25 - 27. 查看DataFrame的索引撮珠、列名、數值
# 查看索引
df2.index
# 查看列名
df.columns
# 查看數值
df.values
28. 查看DataFrame的統(tǒng)計數據
df2.describe()
29. DataFrame的轉置操作
df2.T
30. 對DataFrame進行按列排序
# 根據 age 進行升序排列
df2.sort_values(by='age')
31. 對DataFrame數據切片
df2[1:3]
32. 對DataFrame通過標簽查詢(單列)
df2['age']
# 或
df2.age
33. 對 DataFrame 通過標簽查詢(多列)
df2[['age', 'animal']] # 傳入一個列名組成的列表
34. 對DataFrame通過位置查詢
df2.iloc[1:3] # 查詢 2金矛,3 行
35. DataFrame副本拷貝
# 生成 DataFrame 副本芯急,方便數據集被多個不同流程使用
df3 = df2.copy()
df3
36. 判斷DataFrame元素是否為空
df3.isnull() # 如果為空則返回為 True
37. 添加列數據
num = pd.Series([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], index=df3.index)
df3['No.'] = num # 添加以 'No.' 為列名的新數據列
df3
38. 根據DataFrame的下標值進行修改
# 修改第 2 行與第 2 列對應的值 3.0 → 2.0
df3.iat[1, 1] = 2 # 索引序號從 0 開始,這里為 1, 1
df3
39. 根據DataFrame的標簽對數據進行修改
df3.loc['f', 'age'] = 1.5
df3
40. DataFrame求平均值操作
df3.mean()
41. 對DataFrame中任意列做求和操作
df3['visits'].sum()
字符串操作
42. 將字符串轉化為小寫字母
string = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca',
np.nan, 'CABA', 'dog', 'cat'])
print(string)
string.str.lower()
43. 將字符串轉化為大寫字母
string.str.upper()
DataFrame缺失值操作
44. 對缺失值進行填充
df4 = df3.copy()
print(df4)
df4.fillna(value=3)
45. 刪除存在缺失值的行
df5 = df3.copy()
print(df5)
df5.dropna(how='any') # 任何存在 NaN 的行都將被刪除
46. DataFrame按指定列對齊
left = pd.DataFrame({'key': ['foo1', 'foo2'], 'one': [1, 2]})
right = pd.DataFrame({'key': ['foo2', 'foo3'], 'two': [4, 5]})
print(left)
print(right)
# 按照 key 列對齊連接驶俊,只存在 foo2 相同娶耍,所以最后變成一行
pd.merge(left, right, on='key')
DataFrame文件操作
47. CSV文件寫入
df3.to_csv('animal.csv')
print("寫入成功.")
48. CSV文件讀取
df_animal = pd.read_csv('animal.csv')
df_animal
49. Excel寫入操作
df3.to_excel('animal.xlsx', sheet_name='Sheet1')
print("寫入成功.")
50. Excel讀取操作
pd.read_excel('animal.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
進階部分
時間序列索引
51. 建立一個以 2018 年每一天為索引,值為隨機數的 Series
dti = pd.date_range(start='2018-01-01', end='2018-12-31', freq='D')
s = pd.Series(np.random.rand(len(dti)), index=dti)
s
52. 統(tǒng)計s
中每一個周三對應值的和
# 周一從 0 開始
s[s.index.weekday == 2].sum()
53. 統(tǒng)計s
中每個月值的平均值
s.resample('M').mean()
54. 將 Series 中的時間進行轉換(秒轉分鐘)
s = pd.date_range('today', periods=100, freq='S')
ts = pd.Series(np.random.randint(0, 500, len(s)), index=s)
ts.resample('Min').sum()
55. UTC 世界時間標準
s = pd.date_range('today', periods=1, freq='D') # 獲取當前時間
ts = pd.Series(np.random.randn(len(s)), s) # 隨機數值
ts_utc = ts.tz_localize('UTC') # 轉換為 UTC 時間
ts_utc
56. 轉換為上海所在時區(qū)
ts_utc.tz_convert('Asia/Shanghai')
57.不同時間表示方式的轉換
rng = pd.date_range('1/1/2018', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
print(ts)
ps = ts.to_period()
print(ps)
ps.to_timestamp()
Series多重索引
58. 創(chuàng)建多重索引 Series
構建一個 letters = ['A', 'B', 'C']
和 numbers = list(range(10))
為索引饼酿,值為隨機數的多重索引 Series榕酒。
letters = ['A', 'B', 'C']
numbers = list(range(10))
mi = pd.MultiIndex.from_product([letters, numbers]) # 設置多重索引
s = pd.Series(np.random.rand(30), index=mi) # 隨機數
s
59. 多重索引 Series 查詢
# 查詢索引為 1,3故俐,6 的值
s.loc[:, [1, 3, 6]]
60. 多重索引 Series 切片
s.loc[pd.IndexSlice[:'B', 5:]]
DataFrame多重索引
61. 根據多重索引創(chuàng)建 DataFrame
創(chuàng)建一個以 letters = ['A', 'B']
和 numbers = list(range(6))
為索引想鹰,值為隨機數據的多重索引 DataFrame。
frame = pd.DataFrame(np.arange(12).reshape(6, 2),
index=[list('AAABBB'), list('123123')],
columns=['hello', 'shiyanlou'])
frame
62. 多重索引設置列名稱
frame.index.names = ['first', 'second']
frame
63. DataFrame 多重索引分組求和
frame.groupby('first').sum()
64. DataFrame 行列名稱轉換
print(frame)
frame.stack()
65. DataFrame 索引轉換
print(frame)
frame.unstack()
66. DataFrame 條件查找
# 示例數據
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}
labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=labels)
查找 age
大于 3
的全部信息
df[df['age'] > 3]
67. 根據行列索引切片
df.iloc[2:4, 1:3]
68. DataFrame 多重條件查詢
查找 age<3
且為 cat
的全部數據药版。
df = pd.DataFrame(data, index=labels)
df[(df['animal'] == 'cat') & (df['age'] < 3)]
69. DataFrame 按關鍵字查詢
df3[df3['animal'].isin(['cat', 'dog'])]
70. DataFrame 按標簽及列名查詢辑舷。
df.loc[df2.index[[3, 4, 8]], ['animal', 'age']]
71. DataFrame 多條件排序
按照 age
降序,visits
升序排列
df.sort_values(by=['age', 'visits'], ascending=[False, True])
72.DataFrame 多值替換
將 priority
列的 yes
值替換為 True
槽片,no
值替換為 False
何缓。
df['priority'].map({'yes': True, 'no': False})
73. DataFrame 分組求和
df4.groupby('animal').sum()
74. 使用列表拼接多個 DataFrame
temp_df1 = pd.DataFrame(np.random.randn(5, 4)) # 生成由隨機數組成的 DataFrame 1
temp_df2 = pd.DataFrame(np.random.randn(5, 4)) # 生成由隨機數組成的 DataFrame 2
temp_df3 = pd.DataFrame(np.random.randn(5, 4)) # 生成由隨機數組成的 DataFrame 3
print(temp_df1)
print(temp_df2)
print(temp_df3)
pieces = [temp_df1, temp_df2, temp_df3]
pd.concat(pieces)
75. 找出 DataFrame 表中和最小的列
df = pd.DataFrame(np.random.random(size=(5, 10)), columns=list('abcdefghij'))
print(df)
df.sum().idxmin() # idxmax(), idxmin() 為 Series 函數返回最大最小值的索引值
76. DataFrame 中每個元素減去每一行的平均值
df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
df.sub(df.mean(axis=1), axis=0)
77. DataFrame 分組,并得到每一組中最大三個數之和
df = pd.DataFrame({'A': list('aaabbcaabcccbbc'),
'B': [12, 345, 3, 1, 45, 14, 4, 52, 54, 23, 235, 21, 57, 3, 87]})
print(df)
df.groupby('A')['B'].nlargest(3).sum(level=0)
透視表
當分析龐大的數據時还栓,為了更好的發(fā)掘數據特征之間的關系歌殃,且不破壞原數據,就可以利用透視表 pivot_table
進行操作蝙云。
78. 透視表的創(chuàng)建
新建表將 A, B, C
列作為索引進行聚合氓皱。
df = pd.DataFrame({'A': ['one', 'one', 'two', 'three'] * 3,
'B': ['A', 'B', 'C'] * 4,
'C': ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
'D': np.random.randn(12),
'E': np.random.randn(12)})
print(df)
pd.pivot_table(df, index=['A', 'B'])
79. 透視表按指定行進行聚合
將該 DataFrame 的 D
列聚合,按照 A,B
列為索引進行聚合,聚合的方式為默認求均值波材。
pd.pivot_table(df, values=['D'], index=['A', 'B'])
80. 透視表聚合方式定義
上一題中 D
列聚合時股淡,采用默認求均值的方法,若想使用更多的方式可以在 aggfunc
中實現廷区。
pd.pivot_table(df, values=['D'], index=['A', 'B'], aggfunc=[np.sum, len])
81. 透視表利用額外列進行輔助分割
D
列按照 A,B
列進行聚合時唯灵,若關心 C
列對 D
列的影響,可以加入 columns
值進行分析隙轻。
pd.pivot_table(df, values=['D'], index=['A', 'B'],
columns=['C'], aggfunc=np.sum)
82. 透視表的缺省值處理
在透視表中由于不同的聚合方式,相應缺少的組合將為缺省值玖绿,可以加入 fill_value
對缺省值處理敛瓷。
pd.pivot_table(df, values=['D'], index=['A', 'B'],
columns=['C'], aggfunc=np.sum, fill_value=0)
絕對類型
在數據的形式上主要包括數量型和性質型,數量型表示著數據可數范圍可變斑匪,而性質型表示范圍已經確定不可改變,絕對型數據就是性質型數據的一種蚀瘸。
83. 絕對型數據定義
df = pd.DataFrame({"id": [1, 2, 3, 4, 5, 6], "raw_grade": [
'a', 'b', 'b', 'a', 'a', 'e']})
df["grade"] = df["raw_grade"].astype("category")
df
84. 對絕對型數據重命名
df["grade"].cat.categories = ["very good", "good", "very bad"]
df
85. 重新排列絕對型數據并補充相應的缺省值
df["grade"] = df["grade"].cat.set_categories(
["very bad", "bad", "medium", "good", "very good"])
df
86. 對絕對型數據進行排序
df.sort_values(by="grade")
87. 對絕對型數據進行分組
df.groupby("grade").size()
數據清洗
常常我們得到的數據是不符合我們最終處理的數據要求狡蝶,包括許多缺省值以及壞的數據,需要我們對數據進行清洗贮勃。
88. 缺失值擬合
在FilghtNumber
中有數值缺失贪惹,其中數值為按 10 增長,補充相應的缺省值使得數據完整寂嘉,并讓數據為 int
類型馍乙。
df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm',
'Budapest_PaRis', 'Brussels_londOn'],
'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )',
'12. Air France', '"Swiss Air"']})
df['FlightNumber'] = df['FlightNumber'].interpolate().astype(int)
df
89. 數據列拆分
其中From_to
應該為兩獨立的兩列From
和To
,將From_to
依照_
拆分為獨立兩列建立為一個新表垫释。
temp = df.From_To.str.split('_', expand=True)
temp.columns = ['From', 'To']
temp
90. 字符標準化
其中注意到地點的名字都不規(guī)范(如:londON
應該為London
)需要對數據進行標準化處理丝格。
temp['From'] = temp['From'].str.capitalize()
temp['To'] = temp['To'].str.capitalize()
91. 刪除壞數據加入整理好的數據
將最開始的 From_to
列刪除,加入整理好的 From
和 to
列棵譬。
df = df.drop('From_To', axis=1)
df = df.join(temp)
print(df)
91. 刪除壞數據加入整理好的數據
將最開始的 From_to
列刪除显蝌,加入整理好的 From
和 to
列。
df = df.drop('From_To', axis=1)
df = df.join(temp)
print(df)
93. 格式規(guī)范
在 RecentDelays
中記錄的方式為列表類型订咸,由于其長度不一曼尊,這會為后期數據分析造成很大麻煩。這里將 RecentDelays
的列表拆開脏嚷,取出列表中的相同位置元素作為一列骆撇,若為空值即用 NaN
代替。
delays = df['RecentDelays'].apply(pd.Series)
delays.columns = ['delay_{}'.format(n) for n in range(1, len(delays.columns)+1)]
df = df.drop('RecentDelays', axis=1).join(delays)
df
數據預處理
94. 信息區(qū)間劃分
班級一部分同學的數學成績表父叙,如下圖所示
df=pd.DataFrame({'name':['Alice','Bob','Candy','Dany','Ella','Frank','Grace','Jenny'],'grades':[58,83,79,65,93,45,61,88]})
但我們更加關心的是該同學是否及格神郊,將該數學成績按照是否>60
來進行劃分肴裙。
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Candy', 'Dany', 'Ella',
'Frank', 'Grace', 'Jenny'], 'grades': [58, 83, 79, 65, 93, 45, 61, 88]})
def choice(x):
if x > 60:
return 1
else:
return 0
df.grades = pd.Series(map(lambda x: choice(x), df.grades))
df
95. 數據去重
一個列為A
的 DataFrame 數據,如下圖所示
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
嘗試將 A 列中連續(xù)重復的數據清除涌乳。
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
df.loc[df['A'].shift() != df['A']]
96. 數據歸一化
有時候蜻懦,DataFrame 中不同列之間的數據差距太大,需要對其進行歸一化處理夕晓。
其中宛乃,Max-Min 歸一化是簡單而常見的一種方式.
def normalization(df):
numerator = df.sub(df.min())
denominator = (df.max()).sub(df.min())
Y = numerator.div(denominator)
return Y
df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
normalization(df)
Pandas繪圖操作
為了更好的了解數據包含的信息,最直觀的方法就是將其繪制成圖蒸辆。
97. Series 可視化
%matplotlib inline
ts = pd.Series(np.random.randn(100), index=pd.date_range('today', periods=100))
ts = ts.cumsum()
ts.plot()
98. DataFrame 折線圖
df = pd.DataFrame(np.random.randn(100, 4), index=ts.index,
columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
df.plot()
99. DataFrame 散點圖
df = pd.DataFrame({"xs": [1, 5, 2, 8, 1], "ys": [4, 2, 1, 9, 6]})
df = df.cumsum()
df.plot.scatter("xs", "ys", color='red', marker="*")
100. DataFrame 柱形圖
df = pd.DataFrame({"revenue": [57, 68, 63, 71, 72, 90, 80, 62, 59, 51, 47, 52],
"advertising": [2.1, 1.9, 2.7, 3.0, 3.6, 3.2, 2.7, 2.4, 1.8, 1.6, 1.3, 1.9],
"month": range(12)
})
ax = df.plot.bar("month", "revenue", color="yellow")
df.plot("month", "advertising", secondary_y=True, ax=ax)