天天看點

Pandas之DataFrame詳解

二維資料,Series容器,既有行索引,又有列索引
Pandas之DataFrame詳解

1. 建立DataFrame

1.1 通過list 建立DataFrame

需要指定 data,index 行,columns 列

指定data和index/columns是list類型或者 np.arange

df1 = pd.DataFrame(data=[[1, 2, 3], [11, 12, 13]], index=['r_1', 'r_2'], columns=['A', 'B', 'C'])
df2 = pd.DataFrame(data=[[1], [11]], index=['r_1', 'r_2'], columns=['A'])
df3 = pd.DataFrame(data=np.arange(12).reshape(3, 4), index=list("abc"), columns=list("ABCD"))
複制代碼
           

A B C

r_1 1 2 3 r_2 11 12 13

​ A r_1 1 r_2 11

A B C D a 0 1 2 3 b 4 5 6 7 c 8 9 10 11

1.2 通過字典,建立DataFrame

1.2.1 方式一:傳入單個字典, 注意必須是一鍵多值(單值的時候,也必須加上[])

dict = {"name": ["jack", "HanMeimei"], "age": ["100", "100"]}
# dict = {"name": "jack", "age": "100"}#這樣寫是會報錯的
# dict = {"name":["jack"], "age": ["100"]}#如果是單值,必須加[]
df3 = pd.DataFrame(dict, index=list("ab"))
複制代碼
           

age age1 name

a 100.0 NaN MaYun1 b 100.0 NaN MaYun2 c NaN 100.0 MaYun3

1.2.2 方式二: 傳入字典清單,每一個字典是一行資料,缺少的列會補充nan

dict = [{"name": "MaYun1", "age": 100}, {"name": "MaYun2", "age": 100}, {"name": "MaYun3", "age1": 100}]
# dict = {"name": "jack", "age": "100"}
df4 = pd.DataFrame(dict, index=list("abc"))
複制代碼
           

2. DataFrame基本屬性

Pandas之DataFrame詳解
dict = {"name": ["jack", "HanMeimei", "Lucy"], "age": ["100", "90","98"], "salary": [30000, 50000, 999000]}
df5 = pd.DataFrame(dict)
print(df5)
print(df5.head(1))
print(df5.tail(1))
print(df5.info())
print(df5.index)
print(df5.columns)
print(df5.values)
print(df5.describe())
複制代碼
           

3. 所有資料按照指定列排序

df5 = df5.sort_values(by='salary', ascending=True)
print(df5)
複制代碼
           
Pandas之DataFrame詳解

4. DataFrame簡單行、列切片

dict = {"name": ["jack", "HanMeimei", "Lucy","Mr Green", "Mrs Han", "Lily"],
        "age": [100, 90,98,90,100,30], "salary": [30000, 50000, 999000,90000,80000,75000]}
df6 = pd.DataFrame(dict)
print(df6)

# 取出前五行
print(df6[0:5])
# 取出name列
print(df6["name"])
# 取出前三行的name列
print(df6[0:3]["name"])
複制代碼
           
Pandas之DataFrame詳解

5. loc 行、列切片

5.2 *記住下面的這一個就行了,記太多反而麻煩

基本格式為:

df7.loc[行,列]
複制代碼
           

如果取連續的行或者列---使用切片 :

如果取出來不連續的行或列—使用清單 [ ]

其中 切片和清單可以混合使用

舉列:

5.5.1 連續多行多列

df7.loc['a':'c','name':'age']

注意:包含了b行,因為是行切片
>       name  age
a       jack  100
b  HanMeimei   90
c       Lucy   98
複制代碼
           

5.5.2 不連續多行+連續多列

df7.loc[['a','c'],'name':'salary']
注意:行是不連續選擇,隻是a和c
	 列是連續切片,包含了中間的age
>   name  age  salary
a  jack  100   30000
c  Lucy   98  999000
複制代碼
           

5.5.3 不連續多行+不連續多列

df7.loc[['a','c'],['name','salary']]
注意:行是不連續選擇,隻是a和c
	 列也是不連續選擇,隻是name和salary
>    name  salary
a  jack   30000
c  Lucy  999000
複制代碼
           

5.5.4 全部行+不連續多列(全部列同理)

df7.loc[:,['name','salary']]
注意:隻要把行寫個空切片就行   :
>   	    name  salary
	a       jack   30000
	b  HanMeimei   50000
	c       Lucy  999000
	d   Mr Green   90000
	e    Mrs Han   80000
	f       Lily   75000
複制代碼
           

5.5.5 不連續多行+單列(單行同理)

df7.loc[['a','c'],'name']
注意:單列名沒加[],結果是個Series
> 	a    jack
	c    Lucy
	Name: name, dtype: object
	<class 'pandas.core.series.Series'>
複制代碼
           
df7.loc[['a','c'],['name']]
type(df7.loc[['a','c'],['name']])
注意:單列名加[],結果是個DataFrame
>	   name
	a  jack
	c  Lucy
	<class 'pandas.core.frame.DataFrame'>
複制代碼
           

6. iloc 行、列切片

隻是通過位置取值,原理與loc一樣

隻是注意,切片不包含最後一個數字,這點與loc不同

Pandas之DataFrame詳解
Pandas之DataFrame詳解
df7.iloc[[1,3],[0]]
> 取得不連續的行列
        name
b  HanMeimei
d   Mr Green


df7.iloc[1:3,0:1]
> 沒包含3的d ,沒包含1的age
        name
b  HanMeimei
c       Lucy
複制代碼
           

7. 指派更改資料

可以使用loc,也可以使用iloc

Pandas之DataFrame詳解
df7.iloc[1:3,1:3]=99999999
print(df7)
>       name       age    salary
a       jack       100     30000
b  HanMeimei  99999999  99999999
c       Lucy  99999999  99999999
d   Mr Green        90     90000
e    Mrs Han       100     80000
f       Lily        30     75000
複制代碼
           

8.布爾索引

一起看個例子吧

建立一個dataframe

Score = {"姓名": ["張無忌", "趙敏", "小喬", "大喬", "楊玉環", "貂蟬", "西施", "王子", "姜子牙", "李白", "杜甫", "王偉","李曉雨"],
         "國文": [78, 90, 87, 88, 56, 94, 92, 85, 93, 91, 59, 100,100],
         "數學": [91, 59, 100, 75, 30, 95, 91, 59, 100, 10, 95, 85,100],
         "英語": [91, 59, 100, 75, 30, 95, 10, 95, 85, 75, 30, 95,100]}
df_score = pd.DataFrame(Score)
print(df_score)
複制代碼
           
Pandas之DataFrame詳解

8.1 取出所有英語成績大于90的人的資料

# 得到的是一個Series
loc_ = df_score.loc[:,"英語"] > 90
print(loc_)
print(type(loc_))# <class 'pandas.core.series.Series'>
# dataframe 布爾索引,會篩選出所有值為true的行
print(df_score[loc_])

# 也可以簡寫為
print(df_score[df_score.loc[:,"英語"]>90])
複制代碼
           
Pandas之DataFrame詳解
Pandas之DataFrame詳解

8.2 取出所有英語成績小于90的人的資料(~)

注意:加 ~ 取反
print(df_score[~(df_score.loc[:, "英語"] > 90)])
複制代碼
           
Pandas之DataFrame詳解

8.3 取出所有英語成績大于90并且國文大于80人的資料

print(df_score[(df_score.loc[:, "英語"] > 90)&(df_score.loc[:, "國文"] < 80)])
複制代碼
           
Pandas之DataFrame詳解

8.4 知識點截圖

Pandas之DataFrame詳解
Pandas之DataFrame詳解

9. 字元串方法

# 建立一個dataframe
student = {"姓名": ["張無忌", "趙敏", "小喬", "大喬", "楊玉環", "貂蟬", "西施", "王子", "姜子牙", "李白", "杜甫", "王偉", "李曉雨"],
           "國文": [78, 90, 87, 88, 56, 94, 92, 85, 93, 91, 59, 100, 100],
           "數學": [91, 59, 100, 75, 30, 95, 91, 59, 100, 10, 95, 85, 100],
           "英語": [91, 59, 100, 75, 30, 95, 10, 95, 85, 75, 30, 95, 100],
           "班級": ["一年級3班", "一年級1班", "二年級3班", "二年級1班", "一年級13班", "三年級7班", "五年級3班", "四年級3班", "一年級5班", "一年級7班", "一年級4班",
                  "一年級9班", "一年級10班"],
           }
df_student = pd.DataFrame(student)
print(df_student)
複制代碼
           
Pandas之DataFrame詳解

9.1 len—選擇【班級】列元素字元串長度大于5的資料

print(df_student[df_student["班級"].str.len() > 5])
複制代碼
           
Pandas之DataFrame詳解

9.2 replace—把【班級】列元素中的【年級】改為【學校一年級】

# 注意等号右側傳回一個Series,要把它指派給原DataFrame對應的列
df_student["班級"] = df_student["班級"].str.replace("一年級", "學校一年級")
print(df_student)
# 下面是取列的loc用法
df_student.loc[:,"班級"] = df_student.loc[:,"班級"].str.replace("一年級", "學校一年級")
複制代碼
           
Pandas之DataFrame詳解

9.3 contains—篩選【班級】列包含“學校”和“1”的資料

print(df_student[
          (df_student["班級"].str.contains("學校"))
          &
          (df_student["班級"].str.contains("1"))])
複制代碼
           
Pandas之DataFrame詳解

9.4 split—切割字元串

Pandas之DataFrame詳解
Pandas之DataFrame詳解

9.5 get—列印學生姓名的第一個字元(姓氏)

print((df_student["姓名"].str.get(0)))
複制代碼
           
Pandas之DataFrame詳解

9.6 match—正規表達式比對,找出姓名包含'王|李'的資料

reg = '王|李'
print(df_student[df_student["姓名"].str.match(reg)])
複制代碼
           
Pandas之DataFrame詳解

9.7 pad—填充字元*

# 注意width=10表示,現在的字元+要填充的*,一起計算寬度為10
# 兩側都加*,最後得到的字元串長度為10,不足用*添加(也可以不寫side,直接使用center函數)
df_student["姓名"] = df_student["姓名"].str.pad(width=10, side='both', fillchar='*')
# 右側都加—,最後得到的字元串長度為20,不足用-添加
df_student["姓名"] = df_student["姓名"].str.pad(width=20, side='right', fillchar='-')
print(df_student)
複制代碼
           
Pandas之DataFrame詳解

9.5 知識點截圖

Pandas之DataFrame詳解

10. 新增一列統計總分 apply方法

10.1 直接相加

df_student["總分"] = df_student["國文"] + df_student["數學"] + df_student["英語"]
複制代碼
           
Pandas之DataFrame詳解

10.2 使用Series的apply方法周遊(apply傳入一個函數,更強大)

df_student['總分'] = pd.Series(df_student.index.tolist()).apply(
    lambda i: df_student.loc[i, "國文"] + df_student.loc[i, "數學"] + df_student.loc[i, "英語"])
    
# 1.為了使用Series的apply方法,根據DataFrame的Index生成一個Series,
pd.Series(df_student.index.tolist())
# 2.後面是一個lambda表達式,也可以定義函數傳遞進去(寫函數就可以做很多處理了),見下例
複制代碼
           
# 讓國文大于90的人,讓他的國文成績再加上1000分,然後求總分
def sum1(i):
    if df_student.loc[i, "國文"] > 90:
        df_student.loc[i, "國文"] = df_student.loc[i, "國文"] + 1000
    return df_student.loc[i, "國文"] + df_student.loc[i, "數學"] + df_student.loc[i, "英語"]


df_student['總分'] = pd.Series(df_student.index.tolist()).apply(
    lambda i: sum1(i))
複制代碼
           
Pandas之DataFrame詳解

11. 缺失資料處理

Pandas之DataFrame詳解
# 使用numpy生成一組随機整數(在0~100之間,形狀為5行7列)
rand = np.random.randint(0, 100, (5, 7))
# 使用numpy上傳的資料生成DataFrame
df = pd.DataFrame(rand, columns=list("ABCDEFG"))
# 定義一些NaN
df.loc[0:3, "A":"B"] = np.nan
print(df)
複制代碼
           
Pandas之DataFrame詳解

11.1 判斷是不是NaN

11.1.1 判斷整個df是不是Nan的情況

# 是null嗎
print(pd.isnull(df))
結果是:DataFrame
複制代碼
           
Pandas之DataFrame詳解
# 不是null嗎
print(pd.notnull(df))
複制代碼
           
Pandas之DataFrame詳解

11.1.2 判斷df指定列是不是Nan的情況

# 列印A列裡資料為NUll的資料
print(df[pd.isnull(df["A"])])
複制代碼
           
Pandas之DataFrame詳解
# 列印A列裡資料不為NUll的資料
print(df[pd.notnull(df["A"])])
複制代碼
           
Pandas之DataFrame詳解

11.2 删除df裡有nan的資料

# 不輸入how參數,預設為any
# 隻要有一個是NaN,就會删除該行
print(df.dropna(axis=0))
複制代碼
           
Pandas之DataFrame詳解
# 隻有全部是NaN,才會删除該行
print(df.dropna(axis=0,how="all"))
複制代碼
           
Pandas之DataFrame詳解