數據整理
Pandas提供的數據整理方法
行、列的插入和刪除
df = DataFrame({'姓名':['a','b'], '學號':['A1','A2'], '成績1':[98,90], '成績2':[87,80]})
行的插入/刪除
# 字典參數, 在末尾插入新行,注意ignore_index=True
df = df.append({'姓名':'d','學號':'A4','成績1':89,'成績2':78}, ignore_index=True)
DataFrame的很多命令並不直接改變原數據框,而是返回新數據框,這和列表的處理方式不同。
要直接修改原數據框,可將命令寫爲df=df.append() 的形式。
刪除行使用drop()方法。
df.drop(2, inplace=True) # 按索引刪除第2行, inplace= True表示就地修改原數據框
列的插入/刪除
創建新列最簡單的方法是直接給一個新列賦值,新列默認插在最後。
要注意提供的數據個數應等於數據框的行數。
df['性別'] = ['M', 'F'] # 增加"性別"列,給新列賦值即可插入列
# 在第4列插入平均成績,插入值由成績1和成績2計算得到
df.insert(4, '平均成績', (df.成績1 + df.成績2) / 2 )
Out:
姓名 學號 成績1 成績2 平均成績 性別
0 a A1 98 87 92.5 M
1 b A2 90 80 85.0 F
刪除列時,可使用如下三種方法。 注意axis=1和inplace參數
df.drop('平均成績', axis = 1, inplace=True)
df.pop('成績1')
del df['成績2']
索引整理
reindex()重建索引
通過reindex()方法重建索引,可實現行列的取捨。重建時保留指定標籤的數據,拋棄未指定的標籤。
df = pd.read_csv("mobile.csv", encoding='cp936', index_col=0)
df2 = df.reindex(['一月', '二月', '四月'])
上例中新數據框df2只保留了一月和二月的數據,丟棄了三月的數據,
同時建立了一個'四月'新標籤,新標籤對應的值默認爲NaN。
df.reindex(['apple', 'huawei','mi'], axis=1) # axis=1在列上重建索引
rename()重命名
如果已有的列名或行索引不太合適,可使用rename()方法進行調整。
df.rename(columns={'apple':'Apple', 'huawei':'HW'}) # 更改列名
Out:
Apple HW oppo
一月 1100 1250 800
二月 1050 1300 850
三月 1200 1328 750
df.rename(index={'一月':'m1', '二月':'m2', '三月':'m3'}) # 更改索引
Out:
apple huawei oppo
m1 1100 1250 800
m2 1050 1300 850
m3 1200 1328 750
set_index()重新設定索引列
如果想用另一列做索引列,可用set_index()方法變更。
df = DataFrame({'姓名':['a','b'], '學號':['A1','A2'], '成績1':[98,90], '成績2':[87,80]})
df3 = df.set_index('學號') # 返回的新數據框將學號列設爲索引
df3.reset_index(inplace=True) # 先將原索引列學號恢復爲數據列
df3.set_index('姓名', inplace=True) # 再將姓名列設爲索引列
重複值處理
數據中含有重複值時,使用下列方法處理。
s = Series(list('abac'))
s.duplicated() # 檢測重複值,返回布爾數組,重複值處顯示True
s.drop_duplicates() # 刪除重複值
df = DataFrame({'c1': ['a', 'a', 'b'], 'c2': ['a', 'b', 'b'], 'c3': ['a', 'b', 'x']}) df.drop_duplicates('c1') # c1列上刪除重複值
排序和排名
排序
排序可按索引或數據值。按索引排序使用sort_index()方法,按數據值排序使用sort_values()方法。排序後返回新的有序集,不改變原數據集。
s = Series([2, 5, 1], index=['d', 'a', 'b'])
s.sort_index() # 按索引'a b d'排序,返回新對象,並不改變原對象
s.sort_values() # 按數據值1 2 5排序
s.sort_index(ascending=False) # 按索引逆序排
對數據框排序時,可以設定axis參數以指定按行或按列排序。
np.random.seed(7)
arr = np.array(np.random.randint(1, 100, size=9)).reshape(3, 3)
df = DataFrame(arr.reshape(3, 3), columns=['x','y','z'], index=['a','b','c'])
df.sort_index(axis=1, ascending=False) # 按列名索引降序z y x排列
df.sort_values(by='y') # 按y列的數值排序
df.sort_values(by=['y', 'z']) # 先參照y列,再z列排序
注:無論升序降序,缺失值都排在末尾
排名
排名rank()和排序類似,但會自動生成一個排名號。
s = Series([3, 5, 8, 5], index=list('abcd'))
s.rank() # 排名,默認按數據值升序排名
s.rank(ascending=False) # 降序
s.rank(method='first') # 指定名次號的生成方法爲first
索引a的數值最小,排第1。索引b,d的數值相同,
應排在第2、3名,取平均名次(2+3)/2=2.5,
索引c排在第4。method='first',表示排名相同時不計算平均名次,
而是以數據出現的先後順序排列。
數據框連接
Pandas提供了merge()方法用於連接不同數據框的行,類似於數據庫的連接運算( select sno, name from tb1, tb2 where tb1.sno=tb2.sno )。
df1 = DataFrame({'color':['r', 'b', 'w', 'w'], 'c1':range(4)})
df2 = DataFrame({'color':['b', 'w', 'b'], 'c2':range(2, 5)})
pd.merge(df1, df2) # 或寫爲 pd.merge(df1, df2, on='color')
df1和df2有同名列color,pd.merge()自動將同名列作爲連接鍵,
橫向連接兩個數據框的color值相等的行。連接時丟棄原數據框的索引。
兩個數據框列名不同時,用left_on和right_on參數分別指定。
下例指定c1, c2列爲鍵,表示當df1表的c1列值等於df2表的c2列值時滿足連接條件。
pd.merge(df1, df2, left_on='c1', right_on='c2')
因爲兩個表的color列名相同,所以自動加上後綴_x, _y區分。
pd.merge默認做inner內連接,還可指定left /right/outer 等連接方式,這些連接方式與數據庫中的連接規則是類似的。
df2 = DataFrame({'color':['b', 'w', 'g'], 'c2':range(2, 5)})
pd.merge(df1, df2, how='left') # 包含左表所有的行
pd.merge(df1, df2, how='right') # 包含右表所有的行
pd.merge(df1, df2, how='outer') # 包含兩表所有的行
與連接有關的另一個方法是pd.concat(),它合併兩個數據框。
np.random.seed(7)
df1 = DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
df2 = DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
pd.concat([df1, df2], ignore_index=True) # 默認沿縱向合併,行數增加
pd.concat([df1, df2], axis=1) # axis=1沿橫向合併,列數增加
數據分段
數據分段是將數據按指定的區間歸類,以統計每個區間的數據個數。例如將成績分爲優、良、中、不及格區間段。數據分段的方法是pd.cut(),分段前要自定義數據區間段,並設置對應的標識文字。
np.random.seed(7)
score = np.random.randint(30, 100, size=100) # 生成100個隨機整數
bins = [0, 59, 70, 85, 100] # 定義區間段
labels = ['不及格', '中', '良', '優'] # 設置各段的標識文字
scut = pd.cut(score, bins, labels=labels) # 將score按bins分段
s = pd.value_counts(scut) # 統計各類別的數據個數
# 劃分區間爲 (0,59] < (59, 70] < (70,85] <(85,100]
多級索引
Pandas支持一級索引,也支持多級索引(MultiIndex)。
多級索引可以更好地表達數據之間的聯繫。假定A、B兩類產品都有紅、綠兩種顏色。
x = DataFrame(np.arange(2, 10).reshape(4, 2), index=[list('AABB'), list('rgrg')], columns=['一月','二月']) # 語法1
mindex = pd.Index([('A', 'r'), ('A', 'g'), ('B', 'r'), ('B', 'g')], name=['product', 'color'])
# 創建多級索引數據框 語法2
df = DataFrame(np.arange(2, 10).reshape(4, 2), index=mindex, columns=['一月','二月'])
df有兩級索引(0級和1級),索引分別命名爲product和color。
df.loc['B'] # 查看B類產品
df.loc[('B', 'r')] # 查看B類中的紅色r產品
df.loc[(slice(None), 'r'), :] # 查看所有的紅色r產品
df.loc['A'].sum() # A 類每個月數量和
df.loc['A'].sum().sum() # 所有A類數量和
df.loc[(slice(None), 'r'), :].sum().sum() # r 類數量和
df.groupby(level='product').sum()
df.groupby(level='product').sum().sum(axis=1)
多級索引的數據框常使用stack()和unstack()命令進行轉換。
df2=df.unstack() # 默認將內層的1級行索引轉爲列索引
df2.columns
df3=df.stack() # 變爲三級(0,1,2)索引了
df3.groupby(level=2).sum()