Python大數據處理模塊Pandas
Python大數據處理模塊Pandas
【這篇轉載自CSDNchengxuyuanyonghu的博客:http://blog.csdn.net/chengxuyuanyonghu/article/details/54956207】目錄
- 讀取數據
- 索引
- 選擇數據
- 簡單運算
- import pandas as pd
- read_csv
- to_csv
- 數據框操作
- 一 創建對象
- 二 查看數據
- 三 選擇
- 四 缺失值處理
- 五 相關操作
- 六 合並
- 七 分組
- 八 Reshaping
- 九 時間序列
- 十 Categorical
- 十一 畫圖
- 十二 導入和保存數據
Pandas使用一個二維的數據結構DataFrame來表示表格式的數據,相比較於Numpy,Pandas可以存儲混合的數據結構,同時使用NaN來表示缺失的數據,而不用像Numpy一樣要手工處理缺失的數據,並且Pandas使用軸標簽來表示行和列
1、文件讀取
首先將用到的pandas和numpy加載進來
import pandas as pd
import numpy as np
讀取數據:
#csv和xlsx分別用read_csv和read_xlsx,下面以csv為例
df=pd.read_csv(‘f:\1024.csv‘)
2、查看數據
?
df.head()
?
#默認出5行,?括號裏可以填其他數據
?
3、查看數據類型
?
df.dtypes
?
4、利用現有數據生成一列新數據
?
比如:max_time和min_time是現有的兩列,現在業務需要生成一列gs,gs=max_time-min_time
?
df.[‘gs‘]=df.[‘max_time‘]-[‘min_time‘]
?
#查看是否成功
?
df.head()
?
5、查看基本統計量
?
df.describe(include=‘all‘) # all代表需要將所有列都列出
通常來說,數據是CSV格式,就算不是,至少也可以轉換成CSV格式。在Python中,我們的操作如下:
import pandas as pd
# Reading data locally
df = pd.read_csv(‘/Users/al-ahmadgaidasaad/Documents/d.csv‘)
# Reading data from web
data_url = "https://raw.githubusercontent.com/alstat/Analysis-with-Programming/master/2014/Python/Numerical-Descriptions-of-the-Data/data.csv"
df = pd.read_csv(data_url)
為了讀取本地CSV文件,我們需要pandas這個數據分析庫中的相應模塊。
其中的read_csv函數能夠讀取本地和web數據。
# Head of the data
print df.head()
# OUTPUT
Abra Apayao Benguet Ifugao Kalinga
0 1243 2934 148 3300 10553
1 4158 9235 4287 8063 35257
2 1787 1922 1955 1074 4544
3 17152 14501 3536 19607 31687
4 1266 2385 2530 3315 8520
# Tail of the data
print df.tail()
# OUTPUT
Abra Apayao Benguet Ifugao Kalinga
74 2505 20878 3519 19737 16513
75 60303 40065 7062 19422 61808
76 6311 6756 3561 15910 23349
77 13345 38902 2583 11096 68663
78 2623 18264 3745 16787 16900
上述操作等價於通過print(head(df))來打印數據的前6行,以及通過print(tail(df))來打印數據的後6行。
當然Python中,默認打印是5行,而R則是6行。因此R的代碼head(df, n = 10),
在Python中就是df.head(n = 10),打印數據尾部也是同樣道理。
在Python中,我們則使用columns和index屬性來提取,如下:
# Extracting column names
print df.columns
# OUTPUT
Index([u‘Abra‘, u‘Apayao‘, u‘Benguet‘, u‘Ifugao‘, u‘Kalinga‘], dtype=‘object‘)
# Extracting row names or the index
print df.index
# OUTPUT
Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30], dtype=‘int64‘)
數據轉置使用T方法,
# Transpose data
print df.T
# OUTPUT
0 1 2 3 4 5 6 7 8 9
Abra 1243 4158 1787 17152 1266 5576 927 21540 1039 5424
Apayao 2934 9235 1922 14501 2385 7452 1099 17038 1382 10588
Benguet 148 4287 1955 3536 2530 771 2796 2463 2592 1064
Ifugao 3300 8063 1074 19607 3315 13134 5134 14226 6842 13828
Kalinga 10553 35257 4544 31687 8520 28252 3106 36238 4973 40140
... 69 70 71 72 73 74 75 76 77
Abra ... 12763 2470 59094 6209 13316 2505 60303 6311 13345
Apayao ... 37625 19532 35126 6335 38613 20878 40065 6756 38902
Benguet ... 2354 4045 5987 3530 2585 3519 7062 3561 2583
Ifugao ... 9838 17125 18940 15560 7746 19737 19422 15910 11096
Kalinga ... 65782 15279 52437 24385 66148 16513 61808 23349 68663
78
Abra 2623
Apayao 18264
Benguet 3745
Ifugao 16787
Kalinga 16900
其他變換,例如排序就是用sort屬性。現在我們提取特定的某列數據。
Python中,可以使用iloc或者ix屬性。但是我更喜歡用ix,因為它更穩定一些。假設我們需數據第一列的前5行,我們有:
print df.ix[:, 0].head()
# OUTPUT
0 1243
1 4158
2 1787
3 17152
4 1266
Name: Abra, dtype: int64
順便提一下,Python的索引是從0開始而非1。為了取出從11到20行的前3列數據,我們有:
print df.ix[10:20, 0:3]
# OUTPUT
Abra Apayao Benguet
10 981 1311 2560
11 27366 15093 3039
12 1100 1701 2382
13 7212 11001 1088
14 1048 1427 2847
15 25679 15661 2942
16 1055 2191 2119
17 5437 6461 734
18 1029 1183 2302
19 23710 12222 2598
20 1091 2343 2654
上述命令相當於df.ix[10:20, [‘Abra‘, ‘Apayao‘, ‘Benguet‘]]。
為了舍棄數據中的列,這裏是列1(Apayao)和列2(Benguet),我們使用drop屬性,如下:
print df.drop(df.columns[[1, 2]], axis = 1).head()
# OUTPUT
Abra Ifugao Kalinga
0 1243 3300 10553
1 4158 8063 35257
2 1787 1074 4544
3 17152 19607 31687
4 1266 3315 8520
axis 參數告訴函數到底舍棄列還是行。如果axis等於0,那麽就舍棄行。
統計描述
下一步就是通過describe屬性,對數據的統計特性進行描述:
print df.describe()
# OUTPUT
Abra Apayao Benguet Ifugao Kalinga
count 79.000000 79.000000 79.000000 79.000000 79.000000
mean 12874.379747 16860.645570 3237.392405 12414.620253 30446.417722
std 16746.466945 15448.153794 1588.536429 5034.282019 22245.707692
min 927.000000 401.000000 148.000000 1074.000000 2346.000000
25% 1524.000000 3435.500000 2328.000000 8205.000000 8601.500000
50% 5790.000000 10588.000000 3202.000000 13044.000000 24494.000000
75% 13330.500000 33289.000000 3918.500000 16099.500000 52510.500000
max 60303.000000 54625.000000 8813.000000 21031.000000 68663.000000
Python有一個很好的統計推斷包。那就是scipy裏面的stats。ttest_1samp實現了單樣本t檢驗。因此,如果我們想檢驗數據Abra列的稻谷產量均值,通過零假設,這裏我們假定總體稻谷產量均值為15000,我們有:
from scipy import stats as ss
# Perform one sample t-test using 1500 as the true mean
print ss.ttest_1samp(a = df.ix[:, ‘Abra‘], popmean = 15000)
# OUTPUT
(-1.1281738488299586, 0.26270472069109496)
返回下述值組成的元祖:
t : 浮點或數組類型
t統計量
prob : 浮點或數組類型
two-tailed p-value 雙側概率值
通過上面的輸出,看到p值是0.267遠大於α等於0.05,因此沒有充分的證據說平均稻谷產量不是150000。將這個檢驗應用到所有的變量,同樣假設均值為15000,我們有:
print ss.ttest_1samp(a = df, popmean = 15000)
# OUTPUT
(array([ -1.12817385, 1.07053437, -65.81425599, -4.564575 , 6.17156198]),
array([ 2.62704721e-01, 2.87680340e-01, 4.15643528e-70,
1.83764399e-05, 2.82461897e-08]))
第一個數組是t統計量,第二個數組則是相應的p值。
可視化
Python中有許多可視化模塊,最流行的當屬matpalotlib庫。稍加提及,我們也可選擇bokeh和seaborn模塊。之前的博文中,我已經說明了matplotlib庫中的盒須圖模塊功能。
# Import the module for plotting
import matplotlib.pyplot as plt
plt.show(df.plot(kind = ‘box‘))
現在,我們可以用pandas模塊中集成R的ggplot主題來美化圖表。要使用ggplot,我們只需要在上述代碼中多加一行,
import matplotlib.pyplot as plt
pd.options.display.mpl_style = ‘default‘ # Sets the plotting display theme to ggplot2
df.plot(kind = ‘box‘)
# Import the seaborn library
import seaborn as sns
# Do the boxplot
plt.show(sns.boxplot(df, widths = 0.5, color = "pastel"))
import numpy as np
import scipy.stats as ss
def case(n = 10, mu = 3, sigma = np.sqrt(5), p = 0.025, rep = 100):
m = np.zeros((rep, 4))
for i in range(rep):
norm = np.random.normal(loc = mu, scale = sigma, size = n)
xbar = np.mean(norm)
low = xbar - ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
up = xbar + ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
if (mu > low) & (mu < up):
rem = 1
else:
rem = 0
m[i, :] = [xbar, low, up, rem]
inside = np.sum(m[:, 3])
per = inside / rep
desc = "There are " + str(inside) + " confidence intervals that contain "
"the true mean (" + str(mu) + "), that is " + str(per) + " percent of the total CIs"
return {"Matrix": m, "Decision": desc}
import numpy as np
import scipy.stats as ss
def case2(n = 10, mu = 3, sigma = np.sqrt(5), p = 0.025, rep = 100):
scaled_crit = ss.norm.ppf(q = 1 - p) * (sigma / np.sqrt(n))
norm = np.random.normal(loc = mu, scale = sigma, size = (rep, n))
xbar = norm.mean(1)
low = xbar - scaled_crit
up = xbar + scaled_crit
rem = (mu > low) & (mu < up)
m = np.c_[xbar, low, up, rem]
inside = np.sum(m[:, 3])
per = inside / rep
desc = "There are " + str(inside) + " confidence intervals that contain "
"the true mean (" + str(mu) + "), that is " + str(per) + " percent of the total CIs"
return {"Matrix": m, "Decision": desc}
讀取數據
Pandas使用函數read_csv()來讀取csv文件
import pandas food_info = (‘food_info.csv‘) print(type(food_info))
# 輸出:<class ‘pandas.core.frame.DataFrame‘> 可見讀取後變成一個DataFrame變量
該文件的內容如下:
使用函數head( m )來讀取前m條數據,如果沒有參數m,默認讀取前五條數據
first_rows = food_info.head() first_rows = food_info.head(3)
由於DataFrame包含了很多的行和列,
Pandas使用省略號(...)來代替顯示全部的行和列,可以使用colums屬性來顯示全部的列名
print(food_info.columns)
# 輸出:輸出全部的列名,而不是用省略號代替
Index([‘NDB_No‘, ‘Shrt_Desc‘, ‘Water_(g)‘, ‘Energ_Kcal‘, ‘Protein_(g)‘, ‘Lipid_Tot_(g)‘, ‘Ash_(g)‘, ‘Carbohydrt_(g)‘, ‘Fiber_TD_(g)‘, ‘Sugar_Tot_(g)‘, ‘Calcium_(mg)‘, ‘Iron_(mg)‘, ‘Magnesium_(mg)‘, ‘Phosphorus_(mg)‘, ‘Potassium_(mg)‘, ‘Sodium_(mg)‘, ‘Zinc_(mg)‘, ‘Copper_(mg)‘, ‘Manganese_(mg)‘, ‘Selenium_(mcg)‘, ‘Vit_C_(mg)‘, ‘Thiamin_(mg)‘, ‘Riboflavin_(mg)‘, ‘Niacin_(mg)‘, ‘Vit_B6_(mg)‘, ‘Vit_B12_(mcg)‘, ‘Vit_A_IU‘, ‘Vit_A_RAE‘, ‘Vit_E_(mg)‘, ‘Vit_D_mcg‘, ‘Vit_D_IU‘, ‘Vit_K_(mcg)‘, ‘FA_Sat_(g)‘, ‘FA_Mono_(g)‘, ‘FA_Poly_(g)‘, ‘Cholestrl_(mg)‘], dtype=‘object‘)
可以使用tolist()函數轉化為list
food_info.columns.tolist()
與Numpy一樣,用shape屬性來顯示數據的格式
dimensions = food_info.shapeprint(dimensions) print(dimensions) ?
輸出:(8618,36) , 其中dimensions[0]為8618,dimensions[1]為36
與Numpy一樣,用dtype屬性來顯示數據類型,Pandas主要有以下幾種dtype:
-
object -- 代表了字符串類型
-
int -- 代表了整型
-
float -- 代表了浮點數類型
-
datetime -- 代表了時間類型
-
bool -- 代表了布爾類型
當讀取了一個文件之後,Pandas會通過分析值來推測每一列的數據類型
print()
輸出:每一列對應的數據類型
NDB_No int64
Shrt_Desc object
Water_(g) float64
Energ_Kcal int64
Protein_(g) float64
...
索引
讀取了文件後,Pandas會把文件的一行作為列的索引標簽,使用行數字作為行的索引標簽
註意,行標簽是從數字0開始的
Pandas使用Series數據結構來表示一行或一列的數據,類似於Numpy使用向量來表示數據。Numpy只能使用數字來索引,而Series可以使用非數字來索引數據,當你選擇返回一行數據的時候,Series並不僅僅返回該行的數據,同時還有每一列的標簽的名字。
譬如要返回文件的第一行數據,Numpy就會返回一個列表(但你可能不知道每一個數字究竟代表了什麽)
而Pandas則會同時把每一列的標簽名返回(此時就很清楚數據的意思了)
選擇數據
Pandas使用loc[]方法來選擇行的數據
# 選擇單行數據: food_info.loc[0] # 選擇行標號為0的數據,即第一行數據 food_info.loc[6] # 選擇行標號為6的數據,即第七行數據 # 選擇多行數據: food_info.loc[3:6] # 使用了切片,註意:由於這裏使用loc[]函數,所以返回的是行標號為3,4,5,6的數據,與python的切片不同的是這裏會返回最後的標號代表的數據,但也可以使用python的切片方法:food_info[3:7] food_info.loc[[2,5,10]] # 返回行標號為2,5,10三行數據 練習:返回文件的最後五行 方法一: length = food_info.shape[0] last_rows = food_info.loc[length-5:length-1] 方法二: num_rows = food_info.shape[0] last_rows = food_info[num_rows-5:num_rows] Pandas直接把列名稱填充就能返回該列的數據 ndb_col = food_info["NDB_No"] # 返回列名稱為NDB_No的那一列的數據 zinc_copper = food_info[["Zinc_(mg)", "Copper_(mg)"]] # 返回兩列數據
簡單運算
現在要按照如下公式計算所有食物的健康程度,並按照降序的方式排列結果:
Score=2×(Protein_(g))?0.75×(Lipid_Tot_(g))
對DataFrame中的某一列數據進行算術運算,其實是對該列中的所有元素進行逐一的運算,譬如:
water_energy = food_info["Water_(g)"] * food_info["Energ_Kcal"]
原理:
由於每一列的數據跨度太大,有的數據是從0到100000,而有的數據是從0到10,所以為了盡量減少數據尺度對運算結果的影響,采取最簡單的方法來規範化數據,那就是將每個數值都除以該列的最大值,從而使所有數據都處於0和1之間。其中max()函數用來獲取該列的最大值.
food_info[‘Normalized_Protein‘] = food_info[‘Protein_(g)‘] / food_info[‘Protein_(g)‘].max() food_info[‘Normalized_Fat‘] = food_info[‘Lipid_Tot_(g)‘] / food_info[‘Lipid_Tot_(g)‘].max() food_info[‘Norm_Nutr_Index‘] = food_info["Normalized_Protein"] * 2 - food_info["Normalized_Fat"] * 0.75 註意:上面的兩個語句已經在原來的DataFrame中添加了三列,列名分別為Normalized_Protein和Normalized_Fat,Norm_Nutr_Index。只需要使用中括號和賦值符就能添加新列,類似於字典 對DataFrame的某一列數據排序,只需要使用函數sort()即可 food_info.sort("Sodium_(mg)") # 函數參數為列名,默認是按照升序排序,同時返回一個新的 DataFramefood_info.sort("Norm_Nutr_Index", inplace=True, ascending=False ) # 通過inplace參數來控制在原表排序,而不是返回一個新的對象;ascending參數用來控制是否升序排序
import pandas as pd
read_csv()
讀寫csv數據
df =
pd.read_csv(path)
: 讀入csv文件,形成一個數據框(data.frame)
df = pd.read_csv(path, header=None)
不要把第一行作為header
to_csv()
* 註意,默認會將第一行作為header,並且默認會添加index,所以不需要的話需要手動禁用 *
df.to_csv(path, header=False, index=False)
數據框操作
df.head(1) 讀取頭幾條數據
df.tail(1) 讀取後幾條數據
df[‘date’] 獲取數據框的date列
df.head(1)[‘date’] 獲取第一行的date列
df.head(1)[‘date’][0] 獲取第一行的date列的元素值
sum(df[‘ability’]) 計算整個列的和
df[df[‘date’] == ‘20161111’] 獲取符合這個條件的行
df[df[‘date’] == ‘20161111’].index[0] 獲取符合這個條件的行的行索引的值
df.iloc[1] 獲取第二行
df.iloc[1][‘test2’] 獲取第二行的test2值
10 mins to pandas
df.index 獲取行的索引
df.index[0] 獲取第一個行索引
df.index[-1] 獲取最後一個行索引,只是獲取索引值
df.columns 獲取列標簽
df[0:2] 獲取第1到第2行,從0開始,不包含末端
df.loc[1] 獲取第二行
df.loc[:,’test1’] 獲取test1的那一列,這個冒號的意思是所有行,逗號表示行與列的區分
df.loc[:,[‘test1’,’test2’]] 獲取test1列和test2列的數據
df.loc[1,[‘test1’,’test2’]] 獲取第二行的test1和test2列的數據
df.at[1,’test1’] 表示取第二行,test1列的數據,和上面的方法類似
df.iloc[0] 獲取第一行
df.iloc[0:2,0:2] 獲取前兩行前兩列的數據
df.iloc[[1,2,4],[0,2]] 獲取第1,2,4行中的0,2列的數據
(df[2] > 1).any() 對於Series應用any()方法來判斷是否有符合條件的
?
一、 創建對象
可以通過 Data Structure Intro Setion 來查看有關該節內容的詳細信息。
1、可以通過傳遞一個list對象來創建一個Series,pandas會默認創建整型索引:
2、通過傳遞一個numpy array,時間索引以及列標簽來創建一個DataFrame:
3、通過傳遞一個能夠被轉換成類似序列結構的字典對象來創建一個DataFrame:
4、查看不同列的數據類型:
5、如果你使用的是IPython,使用Tab自動補全功能會自動識別所有的屬性以及自定義的列,下圖中是所有能夠被自動識別的屬性的一個子集:
二、 查看數據
詳情請參閱:Basics Section
1、 查看frame中頭部和尾部的行:
2、 顯示索引、列和底層的numpy數據:
3、 describe()函數對於數據的快速統計匯總:
4、 對數據的轉置:
5、 按軸進行排序
6、 按值進行排序
三、 選擇
雖然標準的Python/Numpy的選擇和設置表達式都能夠直接派上用場,但是作為工程使用的代碼,我們推薦使用經過優化的pandas數據訪問方式: .at, .iat, .loc, .iloc 和 .ix詳情請參閱Indexing and Selecing Data 和 MultiIndex / Advanced Indexing。
l 獲取
1、 選擇一個單獨的列,這將會返回一個Series,等同於df.A:
2、 通過[]進行選擇,這將會對行進行切片
l 通過標簽選擇
1、 使用標簽來獲取一個交叉的區域
2、 通過標簽來在多個軸上進行選擇
3、 標簽切片
4、 對於返回的對象進行維度縮減
5、 獲取一個標量
6、 快速訪問一個標量(與上一個方法等價)
l 通過位置選擇
1、 通過傳遞數值進行位置選擇(選擇的是行)
2、 通過數值進行切片,與numpy/python中的情況類似
3、 通過指定一個位置的列表,與numpy/python中的情況類似
4、 對行進行切片
5、 對列進行切片
6、 獲取特定的值
l 布爾索引
1、 使用一個單獨列的值來選擇數據:
2、 使用where操作來選擇數據:
3、 使用isin()方法來過濾:
l 設置
1、 設置一個新的列:
2、 通過標簽設置新的值:
3、 通過位置設置新的值:
4、 通過一個numpy數組設置一組新值:
上述操作結果如下:
5、 通過where操作來設置新的值:
四、 缺失值處理
在pandas中,使用np.nan來代替缺失值,這些值將默認不會包含在計算中,詳情請參閱:Missing Data Section。
1、 reindex()方法可以對指定軸上的索引進行改變/增加/刪除操作,這將返回原始數據的一個拷貝:、
2、 去掉包含缺失值的行:
3、 對缺失值進行填充:
4、 對數據進行布爾填充:
五、 相關操作
詳情請參與 Basic Section On Binary Ops
-
統計(相關操作通常情況下不包括缺失值)
1、 執行描述性統計:
2、 在其他軸上進行相同的操作:
3、 對於擁有不同維度,需要對齊的對象進行操作。Pandas會自動的沿著指定的維度進行廣播:
-
Apply
1、 對數據應用函數:
-
直方圖
具體請參照:Histogramming and Discretization
-
字符串方法
Series對象在其str屬性中配備了一組字符串處理方法,可以很容易的應用到數組中的每個元素,如下段代碼所示。更多詳情請參考:Vectorized String Methods.
六、 合並
Pandas提供了大量的方法能夠輕松的對Series,DataFrame和Panel對象進行各種符合各種邏輯關系的合並操作。具體請參閱:Merging section
-
Concat
-
Join 類似於SQL類型的合並,具體請參閱:Database style joining
-
Append 將一行連接到一個DataFrame上,具體請參閱Appending:
七、 分組
對於”group by”操作,我們通常是指以下一個或多個操作步驟:
-
(Splitting)按照一些規則將數據分為不同的組;
-
(Applying)對於每組數據分別執行一個函數;
-
(Combining)將結果組合到一個數據結構中;
詳情請參閱:Grouping section
1、 分組並對每個分組執行sum函數:
2、 通過多個列進行分組形成一個層次索引,然後執行函數:
八、 Reshaping
詳情請參閱 Hierarchical Indexing 和 Reshaping。
-
Stack
-
數據透視表,詳情請參閱:Pivot Tables.
可以從這個數據中輕松的生成數據透視表:
九、 時間序列
Pandas在對頻率轉換進行重新采樣時擁有簡單、強大且高效的功能(如將按秒采樣的數據轉換為按5分鐘為單位進行采樣的數據)。這種操作在金融領域非常常見。具體參考:Time Series section。
1、 時區表示:
2、 時區轉換:
3、 時間跨度轉換:
4、 時期和時間戳之間的轉換使得可以使用一些方便的算術函數。
十、 Categorical
從0.15版本開始,pandas可以在DataFrame中支持Categorical類型的數據,詳細 介紹參看:categorical introduction和API documentation。
1、 將原始的grade轉換為Categorical數據類型:
2、 將Categorical類型數據重命名為更有意義的名稱:
3、 對類別進行重新排序,增加缺失的類別:
4、 排序是按照Categorical的順序進行的而不是按照字典順序進行:
5、 對Categorical列進行排序時存在空的類別:
十一、 畫圖
具體文檔參看:Plotting docs
對於DataFrame來說,plot是一種將所有列及其標簽進行繪制的簡便方法:
十二、 導入和保存數據
-
CSV,參考:Writing to a csv file
1、 寫入csv文件:
2、 從csv文件中讀取:
-
HDF5,參考:HDFStores
1、 寫入HDF5存儲:
2、 從HDF5存儲中讀取:
-
Excel,參考:MS Excel
1、 寫入excel文件:
2、 從excel文件中讀取:
Python大數據處理模塊Pandas