推薦關注↓↓↓↓
pandas是做資料分析非常重要的一個模塊,它使得資料分析的作業變得更快更簡單,由于現實世界中資料源的格式非常多,但是pandas也支持了不同資料格式的匯入方法,所以學習pandas非常有必要,
本文首先記錄一下自己學習read_csv的筆記,當然了自己需要用什么,就學習什么,而不是記錄人家read_csv的所有方法,要是想看所有的方法詳解可以去官網,要想學習Pandas建議先看下面2個網站,
官網地址如下:https://pandas.pydata.org/
官網教程如下(十分鐘搞定pandas):https://pandas.pydata.org/pandas-docs/stable/10min.html
NAN (數值資料型別的一類數),全稱Not a Number ,表示未定義或者不可表示的值,
一:read_csv方法
1,準備CSV檔案
Train_A_001.csv檔案內容如下:
0.916,4.37,-1.372,0.102,0.041,0.069,0.018
0.892,3.955,-1.277,0.015,-0.099,-0.066,0.018
0.908,3.334,-1.193,0.033,-0.098,-0.059,0.018
1.013,3.022,-1.082,0.151,0.015,0.035,0.018
1.111,2.97,-1.103,-0.048,-0.175,-0.171,0.019
1.302,3.043,-1.089,0.011,-0.085,-0.097,0.018
1.552,3.017,-1.052,0.066,-0.002,-0.036,0.019
1.832,2.796,-0.933,0.002,-0.028,-0.075,0.019
2.127,2.521,-0.749,0.011,0.041,-0.022,0.019
2.354,2.311,-0.623,-0.038,0.012,-0.056,0.019
2.537,2.024,-0.452,0.039,0.089,0.031,0.019
2.639,1.669,-0.277,-0.005,0.036,-0.008,0.019
2.707,1.314,-0.214,0.013,0.031,-0.005,0.019
2.81,0.926,-0.142,0.062,0.046,0.031,0.019
2,直接讀取檔案內容
read_csv讀取的資料型別為Dataframe,通過obj.dtypes可以查看每列的資料型別
首先說一下,我這段csv檔案是沒有列索引的,那么我的讀取代碼如下可以讀取到什么呢?
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename)
print(data)
結果如下;
0.916 4.37 -1.372 0.102 0.041 0.069 0.018
0 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
1 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
2 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
3 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
4 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
5 1.552 3.017 -1.052 0.066 -0.002 -0.036 0.019
6 1.832 2.796 -0.933 0.002 -0.028 -0.075 0.019
7 2.127 2.521 -0.749 0.011 0.041 -0.022 0.019
8 2.354 2.311 -0.623 -0.038 0.012 -0.056 0.019
9 2.537 2.024 -0.452 0.039 0.089 0.031 0.019
10 2.639 1.669 -0.277 -0.005 0.036 -0.008 0.019
11 2.707 1.314 -0.214 0.013 0.031 -0.005 0.019
12 2.810 0.926 -0.142 0.062 0.046 0.031 0.019
大家可以發現,它默認你有列索引,并且把第一行的資料當做列索引,并且從第二行開始設定了行索引,所以說列索引的設定非常重要,起碼在這里看來是這樣的,那么如何設定呢,下面就具體分析一下,
3,列索引 header=?的含義
當加上header=None的時候,表明原始檔案沒有列索引,這樣的話會默認自動加上,除非你給定名稱,結果如下:
0 1 2 3 4 5 6
0 0.916 4.370 -1.372 0.102 0.041 0.069 0.018
1 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
2 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
3 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
4 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
5 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
6 1.552 3.017 -1.052 0.066 -0.002 -0.036 0.019
7 1.832 2.796 -0.933 0.002 -0.028 -0.075 0.019
8 2.127 2.521 -0.749 0.011 0.041 -0.022 0.019
9 2.354 2.311 -0.623 -0.038 0.012 -0.056 0.019
10 2.537 2.024 -0.452 0.039 0.089 0.031 0.019
11 2.639 1.669 -0.277 -0.005 0.036 -0.008 0.019
12 2.707 1.314 -0.214 0.013 0.031 -0.005 0.019
13 2.810 0.926 -0.142 0.062 0.046 0.031 0.019
當加上header=0的時候,表明原始檔案的第0行為列索引,結果如下:
0.916 4.37 -1.372 0.102 0.041 0.069 0.018
0 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
1 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
2 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
3 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
4 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
5 1.552 3.017 -1.052 0.066 -0.002 -0.036 0.019
6 1.832 2.796 -0.933 0.002 -0.028 -0.075 0.019
7 2.127 2.521 -0.749 0.011 0.041 -0.022 0.019
8 2.354 2.311 -0.623 -0.038 0.012 -0.056 0.019
9 2.537 2.024 -0.452 0.039 0.089 0.031 0.019
10 2.639 1.669 -0.277 -0.005 0.036 -0.008 0.019
11 2.707 1.314 -0.214 0.013 0.031 -0.005 0.019
12 2.810 0.926 -0.142 0.062 0.046 0.031 0.019
從這段代碼我們可以發現,少了一行,所以第一行的代碼也被默認為列索引,
當沒有列索引的時候,我們也可以自己指定索引名稱,方便自己記錄,代碼如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,header=None,names=('a','b','c','d','e','f','g'))
print(data)
通過上述代碼,我們可以指定列索引為a~f,結果如下:
a b c d e f g
0 0.916 4.370 -1.372 0.102 0.041 0.069 0.018
1 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
2 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
3 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
4 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
5 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
6 1.552 3.017 -1.052 0.066 -0.002 -0.036 0.019
7 1.832 2.796 -0.933 0.002 -0.028 -0.075 0.019
8 2.127 2.521 -0.749 0.011 0.041 -0.022 0.019
9 2.354 2.311 -0.623 -0.038 0.012 -0.056 0.019
10 2.537 2.024 -0.452 0.039 0.089 0.031 0.019
11 2.639 1.669 -0.277 -0.005 0.036 -0.008 0.019
12 2.707 1.314 -0.214 0.013 0.031 -0.005 0.019
13 2.810 0.926 -0.142 0.062 0.046 0.031 0.019
4,行索引 index_col = ?的含義
從上面的代碼,我們可以發現,沒有行索引,只要設定了列索引就行,但是真的行索引不重要嗎,當然不是,有些時候有些需求也是需要列索引為自己定義的名稱,這里我們同樣看待,并學習一下:
當設定行索引為None的時候,也就是index_col = None,同時設定列索引的時候,代碼如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None)
print(data)
結果呢,如下:
0 1 2 3 4 5 6
0 0.916 4.370 -1.372 0.102 0.041 0.069 0.018
1 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
2 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
3 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
4 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
5 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
6 1.552 3.017 -1.052 0.066 -0.002 -0.036 0.019
7 1.832 2.796 -0.933 0.002 -0.028 -0.075 0.019
8 2.127 2.521 -0.749 0.011 0.041 -0.022 0.019
9 2.354 2.311 -0.623 -0.038 0.012 -0.056 0.019
10 2.537 2.024 -0.452 0.039 0.089 0.031 0.019
11 2.639 1.669 -0.277 -0.005 0.036 -0.008 0.019
12 2.707 1.314 -0.214 0.013 0.031 -0.005 0.019
13 2.810 0.926 -0.142 0.062 0.046 0.031 0.019
當然了,當設定行索引為0的時候,也就是index_col = 0,則第一列為索引,
5,讀取指定csv的某一列 usecols = [?]
當然了,在做資料分析的許多時候,我們會讀取指定的某一列,使用的函式如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None,usecols=[1])
print(data)
上面意思是使用第一列資料(串列默認從0開始的啊),結果如下:
1
0 4.370
1 3.955
2 3.334
3 3.022
4 2.970
5 3.043
6 3.017
7 2.796
8 2.521
9 2.311
10 2.024
11 1.669
12 1.314
13 0.926
要想一起讀取三列,則代碼如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None,usecols=[1,2,3])
print(data)
結果如下:
1 2 3
0 4.370 -1.372 0.102
1 3.955 -1.277 0.015
2 3.334 -1.193 0.033
3 3.022 -1.082 0.151
4 2.970 -1.103 -0.048
5 3.043 -1.089 0.011
6 3.017 -1.052 0.066
7 2.796 -0.933 0.002
8 2.521 -0.749 0.011
9 2.311 -0.623 -0.038
10 2.024 -0.452 0.039
11 1.669 -0.277 -0.005
12 1.314 -0.214 0.013
13 0.926 -0.142 0.062
6 讀取csv前幾行內容
使用data.head(n)回傳檔案的前n行內容,示例如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data1 = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
#讀取檔案的前5行
headdata = data1.head(5)
print(headdata)
運行效果,回傳前5行所有資料內容:
0 1 2 3 4 5 6
0 0.916 4.370 -1.372 0.102 0.041 0.069 0.018
1 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
2 0.908 3.334 -1.193 0.033 -0.098 -0.059 0.018
3 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
4 1.111 2.970 -1.103 -0.048 -0.175 -0.171 0.019
7,回傳某行-所有列
下面代碼表示了函式loc回傳了第一行所有列的資料,也就是說第一行的資料:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
data1 = data.loc[0,:]
print(data1)
由此我們可以推斷出,某幾行-所有列的資料,代碼如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
# 回傳第n行所有列的資料
data1 = data.loc[[1,3,5],:]
print(data1)
結果展示一下:
0 1 2 3 4 5 6
1 0.892 3.955 -1.277 0.015 -0.099 -0.066 0.018
3 1.013 3.022 -1.082 0.151 0.015 0.035 0.018
5 1.302 3.043 -1.089 0.011 -0.085 -0.097 0.018
8,回傳所有行-所有列
獲取所有行所有列,直接看代碼:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
# 回傳第n行所有列的資料
data1 = data.loc[:,:]
print(data1)
結果就是所有行,所有列,這里就不展示了,
9,回傳某行-所有列
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
# 回傳所有列-某行的資料
data1 = data.loc[:,0]
print(data1)
運行效果如下:
0 0.916
1 0.892
2 0.908
3 1.013
4 1.111
5 1.302
6 1.552
7 1.832
8 2.127
9 2.354
10 2.537
11 2.639
12 2.707
13 2.810
Name: 0, dtype: float64
10,資料統計
describe()統計下資料量,標準值,平均值,最大值等
data.describe()
就拿上面的csv檔案為例,讀取結果,決議如下:
import pandas as pd
filename = r'Train_A/Train_A_001.csv'
data1 = pd.read_csv(filename,index_col=None,header=None)
# print(data1)
print(data1.describe())
結果如下:
0 1 ... 5 6
count 14.000000 14.000000 ... 14.000000 14.000000
mean 1.764286 2.662286 ... -0.030643 0.018643
std 0.748950 0.957612 ... 0.063172 0.000497
min 0.892000 0.926000 ... -0.171000 0.018000
25% 1.037500 2.095750 ... -0.064250 0.018000
50% 1.692000 2.883000 ... -0.029000 0.019000
75% 2.491250 3.037750 ... 0.022000 0.019000
max 2.810000 4.370000 ... 0.069000 0.019000
[8 rows x 7 columns]
11,pandas讀取csv后,獲取列標簽
比如csv檔案內容如下:
cut,flute_1,flute_2,flute_3
1,32.31711361,48.89261732,37.72082548
2,37.914879,49.57081504,37.72082548
3,43.08790971,50.30286727,37.72082548
4,47.8590723,51.08365203,37.84985103
5,52.25032922,51.90828793,38.17266456
6,56.28276562,52.77212655,38.61755643
7,59.97661561,53.6707451,39.17455623
8,63.3512879,54.5999392,39.83415523
9,66.4253909,55.55571585,40.58729178
那么,我們讀取到的資料,一般來說,第一行是列標簽,可是如何獲取第一行的內容呢?如下:
column_headers = list(df.columns.values)
以上面的csv檔案為例,讀取代碼如下:
import pandas as pd
import numpy as np
data = pd.read_csv(file1,header=0,index_col=0)
# print(data)
column_header = list(data.columns.values)
print(column_header)
結果如下:
['flute_1', 'flute_2', 'flute_3']
這樣我們就獲取了結果,
12,取資料總結
以標簽(行、列的名字)為索引選擇資料—— x.loc[行標簽,列標簽]
以位置(第幾行、第幾列)為索引選擇資料—— x.iloc[行位置,列位置]
同時根據標簽和位置選擇資料——x.ix[行,列]
既然了解了pandas,以后也需要使用,那么我就不止想學習讀取csv了,我還想學習基本的pandas資料結構,起碼以后使用會知道一些,下面學習一下pandas其的基本資料結構,
13,迅速獲取資料描述
~info() 獲取總行數,每個屬性的型別,非空值的數量
14,獲取每個值出現的次數
~value_counts() 獲取每個值出現的次數,
housing["ocean_proximity"].value_counts()
# 輸出
<1H OCEAN 9136
INLAND 6551
NEAR OCEAN 2658
NEAR BAY 2290
ISLAND 5
Name: ocean_proximity, dtype: int64
15,scatter_matrix() 通過繪圖比較相關性
代碼如下:
from pandas.plotting import scatter_matrix
attributes = ["median_house_value", "median_income", "total_rooms",
"housing_median_age"]
scatter_matrix(housing[attributes], figsize=(12, 8))
save_fig("scatter_matrix_plot")
16,~dropna() 回傳略去丟失資料部分后的剩余資料
sample_incomplete_rows.dropna(subset=["total_bedrooms"])
17,~fillna() 用指定的方法填充
# 用中位數填充
median = housing["total_bedrooms"].median()
sample_incomplete_rows["total_bedrooms"].fillna(median, inplace=True)
18,~factorize() 將資料轉換為數值型別特征
housing_cat = housing['ocean_proximity']
housing_cat.head(10)
# 輸出
# 17606 <1H OCEAN
# 18632 <1H OCEAN
# 14650 NEAR OCEAN
# 3230 INLAND
# 3555 <1H OCEAN
# 19480 INLAND
# 8879 <1H OCEAN
# 13685 INLAND
# 4937 <1H OCEAN
# 4861 <1H OCEAN
# Name: ocean_proximity, dtype: object
housing_cat_encoded, housing_categories = housing_cat.factorize()
housing_cat_encoded[:10]
# 輸出
# array([0, 0, 1, 2, 0, 2, 0, 2, 0, 0], dtype=int64)
二:pandas的基本資料結構
pandas是基于Numpy的一個非常好用的庫,正如名字一樣,人見人愛,之所以如下,就在于不論是讀取,處理資料,使用它都非常簡單,
pandas有兩種自己獨有的基本資料結構,即使如此,但是它依然只是Python的一個庫,所以Python中有的資料型別在這里依然使用,同樣還可以使用類自己定義的資料型別,只不過,pandas里面又定義了兩種資料型別:Series和DataFrame,
1,Series
series就如同串列一樣,一系列資料,每個資料對應于一個索引值,比如這樣一個串列:[9,3,8],如果跟索引值寫到一起,就是這樣:
這種樣式我們已經熟悉了,不過有些時候,需要將其豎起來表示:
上面兩種,只是表現形式上的差別罷了,
Series就是“豎起來”的串列,舉個例子:
import pandas as pd
s = pd.Series([1,2,3,'python'])
s
0 1
1 2
2 3
3 python
dtype: object
另外一點也很像串列,就是里面的元素的型別,由我們任意決定,
這里,我們實質上創建了一個Series物件,這個物件當然就有其屬性和方法了,比如下面兩個屬性依次可以顯示Series物件的資料值和索引:
s.values
array([1, 2, 3, 'python'], dtype=object)
s.index
RangeIndex(start=0, stop=4, step=1)
由于串列的索引只能是從0開始的整數,Series資料型別在默認情況下,其索引也是如次,不過區別于串列的是,Series可以自定義索引:
s = pd.Series(['java','python'],index=['1','2'])
s
1 java
2 python
dtype: object
自定義索引之后,我們就可以根據索引操作元素,series也可以學習list操作:
s['1']
'java'
當然了,前面定義Series物件的是,用的是串列,即 Series() 方法的引數中,第一個串列就是其資料值,如果需要定義 index,放在后面,依然是一個串列,除了這種方法之外,還可以用下面的方法定義 Series 物件:
s = {'python':800,'java':600,'c++':1000}
s = pd.Series(s)
s
python 800
java 600
c++ 1000
dtype: int64
這樣的話,索引依然可以自定義,pandas的優勢就在這里體現出來,如果自定義了索引,自定的索引會自動尋找原來的索引,如果一樣的話,就取代原來索引對應的值,這個可以簡稱為“自動對齊”,我們舉例說明:
s = pd.Series(s,index=['python','java','c','c++'])
s
python 800.0
java 600.0
c NaN
c++ 1000.0
dtype: float64
在里面,沒有c,但是索引引數中有,于是其他能夠“自動對齊”的照搬原值,依然可以在新的Series物件的索引中存在,并且可以自動為其賦值NaN,如果pandas中沒有值,都對齊賦值給NaN,下面來一個更特殊的:
ilist = ['a','b','c']
s = pd.Series(s,index=ilist)
s
a NaN
b NaN
c NaN
dtype: float64
這樣的話,新得到的Series物件索引與s物件的值一個也不對應,所以都是NaN,pandas有專門的方法來判斷值是否為空,
pd.isnull(s)
a True
b True
c True
dtype: bool
也可以判斷不為空:
pd.notnull(s)
a False
b False
c False
dtype: bool
當然了,也可以對索引的名字,重新定義:
s = [1,2,3,4]
s = pd.Series(s,index=['python','java','c','c++'])
s
python 1
java 2
c 3
c++ 4
dtype: int64
s.index = ['a','b','c','d']
s
a 1
b 2
c 3
d 4
dtype: int64
2,DataFrame
DataFrame是一個表格型的資料結構,它含有一組有序的列,每類可以是不同的值型別(數值,字串,布林值),DataFrame既有行索引也有列索引,它可以被看做由Series組成的字典(共同使用同一個索引),跟其他類似的資料結構相比(如R的data.frame)DataFrame中面向行和面向列的操作基本上是平衡的,其實DataFrame中的資料是以一個或者多個二維塊存放的(而不是串列,字典或者其他一維資料結構),
DataFrame 是一種二維的資料結構,非常接近于電子表格或者類似 mysql 資料庫的形式,它的豎行稱之為 columns,橫行跟前面的 Series 一樣,稱之為 index,也就是說可以通過 columns 和 index 來確定一個主句的位置,(有人把 DataFrame 翻譯為“資料框”,是不是還可以稱之為“筐”呢?向里面裝資料嘛,)
首先給一個例子:
>>> import pandas as pd
>>> from pandas import Series, DataFrame
>>> data = {"name":["yahoo","google","facebook"], "marks":
[200,400,800], "price":[9, 3, 7]}
>>> f1 = DataFrame(data)
>>> f1
marks name price
0 200 yahoo 9
1 400 google 3
2 800 facebook 7
這是定義一個 DataFrame 物件的常用方法——使用 dict 定義,字典的“鍵”("name","marks","price")就是 DataFrame 的 columns 的值(名稱),字典中每個“鍵”的“值”是一個串列,它們就是那一豎列中的具體填充資料,上面的定義中沒有確定索引,所以,按照慣例(Series 中已經形成的慣例)就是從 0 開始的整數,從上面的結果中很明顯表示出來,這就是一個二維的資料結構(類似 excel 或者 mysql 中的查看效果),
上面的資料顯示中,columns 的順序沒有規定,就如同字典中鍵的順序一樣,但是在 DataFrame 中,columns 跟字典鍵相比,有一個明顯不同,就是其順序可以被規定,向下面這樣做:
>>> f2 = DataFrame(data, columns=['name','price','marks'])
>>> f2
name price marks
0 yahoo 9 200
1 google 3 400
2 facebook 7 800
跟Series類似的,DataFrame資料的索引也可以自定義:
>>> f3 = DataFrame(data, columns=['name', 'price', 'marks', 'debt'], index=['a','b','c'])
>>> f3
name price marks debt
a yahoo 9 200 NaN
b google 3 400 NaN
c facebook 7 800 NaN
大家還要注意觀察上面的顯示結果,因為在定義 f3 的時候,columns 的引數中,比以往多了一項('debt'),但是這項在 data 這個字典中并沒有,所以 debt 這一豎列的值都是空的,在 Pandas 中,空就用 NaN 來代表了,
定義 DataFrame 的方法,除了上面的之外,還可以使用“字典套字典”的方式,
>>> newdata = {"lang":{"firstline":"python","secondline":"java"}, "price":{"firstline":8000}}
>>> f4 = DataFrame(newdata)
>>> f4
lang price
firstline python 8000
secondline java NaN
在字典中就規定好數列名稱(第一層鍵)和每橫行索引(第二層字典鍵)以及對應的資料(第二層字典值),也就是在字典中規定好了每個資料格子中的資料,沒有規定的都是空,
>>> DataFrame(newdata, index=["firstline","secondline","thirdline"])
lang price
firstline python 8000
secondline java NaN
thirdline NaN NaN
如果額外確定了索引,就如同上面顯示一樣,除非在字典中有相應的索引內容,否則都是 NaN,
前面定義了 DataFrame 資料(可以通過兩種方法),它也是一種物件型別,比如變數 f3 參考了一個物件,它的型別是 DataFrame,承接以前的思維方法:物件有屬性和方法,
>>> f3.columns
Index(['name', 'price', 'marks', 'debt'], dtype=object)
DataFrame 物件的 columns 屬性,能夠顯示素有的 columns 名稱,并且,還能用下面類似字典的方式,得到某豎列的全部內容(當然包含索引):
>>> f3['name']
a yahoo
b google
c facebook
Name: name
這是什么?這其實就是一個 Series,或者說,可以將 DataFrame 理解為是有一個一個的 Series 組成的,
一直耿耿于懷沒有數值的那一列,下面的操作是統一給那一列賦值:
>>> f3['debt'] = 89.2
>>> f3
name price marks debt
a yahoo 9 200 89.2
b google 3 400 89.2
c facebook 7 800 89.2
除了能夠統一賦值之外,還能夠“點對點”添加數值,結合前面的 Series,既然 DataFrame 物件的每豎列都是一個 Series 物件,那么可以先定義一個 Series 物件,然后把它放到 DataFrame 物件中,如下:
>>> sdebt = Series([2.2, 3.3], index=["a","c"]) #注意索引
>>> f3['debt'] = sdebt
將 Series 物件(sdebt 變數所參考) 賦給 f3['debt']列,Pandas 的一個重要特性——自動對齊——在這里起做用了,在 Series 中,只有兩個索引("a","c"),它們將和 DataFrame 中的索引自動對齊,于是乎:
>>> f3
name price marks debt
a yahoo 9 200 2.2
b google 3 400 NaN
c facebook 7 800 3.3
自動對齊之后,沒有被復制的依然保持 NaN,
還可以更精準的修改資料嗎?當然可以,完全仿照字典的操作:
>>> f3["price"]["c"]= 300
>>> f3
name price marks debt
a yahoo 9 200 2.2
b google 3 400 NaN
c facebook 300 800 3.3
3,pandas.DataFrame.values
DataFrame.values 回傳DataFrame的Numpy表示形式
僅回傳DataFrame中的值,將洗掉軸標簽
示例一:
所有列都是相同型別(例如:int64)的DataFrame會生成相同型別的陣列,
>>> df = pd.DataFrame({'age': [ 3, 29],
... 'height': [94, 170],
... 'weight': [31, 115]})
>>> df
age height weight
0 3 94 31
1 29 170 115
>>> df.dtypes
age int64
height int64
weight int64
dtype: object
>>> df.values
array([[ 3, 94, 31],
[ 29, 170, 115]], dtype=int64)
示例二:
具有混合型別列的DataFrame(例如,str / object,int64,float32)導致最寬泛型別的ndarray,其適應這些混合型別(例如,物件),
>>> df2 = pd.DataFrame([('parrot', 24.0, 'second'),
... ('lion', 80.5, 1),
... ('monkey', np.nan, None)],
... columns=('name', 'max_speed', 'rank'))
>>> df2.dtypes
name object
max_speed float64
rank object
dtype: object
>>> df2.values
array([['parrot', 24.0, 'second'],
['lion', 80.5, 1],
['monkey', nan, None]], dtype=object)
三,DataFrame切片大全(包含多重索引)
這節主要學習如何對pandas的DataFrame進行切片,包括取某行,某列,某幾行,某幾列以及多重索引的取數方法,
測驗的CSV檔案如下(test.csv):
注意:測驗資料沒有行標題和列標題
2.95072,3.37973,3.03758,0.711681,3.37973,3.37973
2.95072,3.37973,3.03758,0.711681,3.37973,3.37973
3.19946,3.72793,3.22612,0.899132,3.72793,3.72793
3.23699,3.72295,3.29885,0.988473,3.72295,3.72295
3.23179,3.71829,3.29314,0.96549,3.71829,3.71829
3.29573,3.76237,3.32046,0.978557,3.76237,3.76237
3.32537,3.82346,3.35758,1.04363,3.82346,3.82346
3.34407,3.87181,3.38804,1.05891,3.87181,3.87181
3.4196,3.88913,3.44196,1.12763,3.88913,3.88913
3.3904,3.87997,3.42206,1.10885,3.87997,3.87997
首先說明一下,直接read_csv和轉換為DataFrame的效果,
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'])
print(type(filecontent))
df = pd.DataFrame(filecontent)
print(type(df))
先看結果:
<class 'pandas.core.frame.DataFrame'>
<class 'pandas.core.frame.DataFrame'>
從結果來看,所以說兩個效果是一樣的,轉不轉換都一樣,
1,取DataFrame的某列三種方法
直接拿第四列的資料(串列默認從0開始取),代碼如下:
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None)
df = pd.DataFrame(filecontent,index=None)
index4 = df.iloc[:,3]
print(index4)
結果:
0 0.711681
1 0.711681
2 0.899132
3 0.988473
4 0.965490
5 0.978557
6 1.043630
7 1.058910
8 1.127630
9 1.108850
Name: 3, dtype: float64
當加上索引,就取索引,兩個效果是一樣的,代碼如下:
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'])
print(filecontent.a)
print(filecontent['a'])
結果:
0 2.95072
1 2.95072
2 3.19946
3 3.23699
4 3.23179
5 3.29573
6 3.32537
7 3.34407
8 3.41960
9 3.39040
Name: a, dtype: float64
0 2.95072
1 2.95072
2 3.19946
3 3.23699
4 3.23179
5 3.29573
6 3.32537
7 3.34407
8 3.41960
9 3.39040
Name: a, dtype: float64
2,取DataFrame某幾列的兩種方法
使用索引和不適用索引取多列的方法
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'])
df = pd.DataFrame(filecontent)
# 取某幾列的方法一使用索引
result = df[['b','c']]
print(result)
# 取某幾列的方法一不使用索引取前兩列
result1 = df.iloc[:,:2]
print(result1)
結果:
b c
0 3.37973 3.03758
1 3.37973 3.03758
2 3.72793 3.22612
3 3.72295 3.29885
4 3.71829 3.29314
5 3.76237 3.32046
6 3.82346 3.35758
7 3.87181 3.38804
8 3.88913 3.44196
9 3.87997 3.42206
a b
0 2.95072 3.37973
1 2.95072 3.37973
2 3.19946 3.72793
3 3.23699 3.72295
4 3.23179 3.71829
5 3.29573 3.76237
6 3.32537 3.82346
7 3.34407 3.87181
8 3.41960 3.88913
9 3.39040 3.87997
3,取DataFrame的某行三種方法
代碼如下;
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'])
df = pd.DataFrame(filecontent)
# 取某幾行的方法一使用索引
result = df[1:2]
print(result)
print('************************************************')
# 取某幾列的方法一不使用索引取第一行
result1 = df.ix[1]
print(result1)
print('************************************************')
# 取某幾列的方法一不使用索引取第一行
result2 = df.iloc[1,:]
print(result2)
結果如下:
a b c d e f
1 2.95072 3.37973 3.03758 0.711681 3.37973 3.37973
************************************************
a 2.950720
b 3.379730
c 3.037580
d 0.711681
e 3.379730
f 3.379730
Name: 1, dtype: float64
************************************************
a 2.950720
b 3.379730
c 3.037580
d 0.711681
e 3.379730
f 3.379730
Name: 1, dtype: float64
4,取DataFrame的某幾行的方法
代碼如下:
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'],index_col=None)
df = pd.DataFrame(filecontent)
# 取某幾行的方法一不使用索引取前兩行
result1 = df.iloc[:2,]
print(result1)
結果如下:
a b c d e f
0 2.95072 3.37973 3.03758 0.711681 3.37973 3.37973
1 2.95072 3.37973 3.03758 0.711681 3.37973 3.37973
5,取DataFrame的某特定位置元素的方法
代碼如下:
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'],index_col=None)
df = pd.DataFrame(filecontent)
# 取DataFrame的某特定位置元素的方法
result = df.ix[1,2]
print(result)
結果如下:
3.0375799999999997
6,取DataFrame的多行多列的方法
代碼如下:
import pandas as pd
filecontent = pd.read_csv('test.csv',header=None,names=['a','b','c','d','e','f'],index_col=None)
df = pd.DataFrame(filecontent)
# 取DataFrame的多行多列的方法
# 取前兩行,前三列
result = df.ix[:2,:3]
print(result)
# 取前兩行,前三列
result1 = df.iloc[:2,:3]
print(result1)
結果如下:
a b c
0 2.95072 3.37973 3.03758
1 2.95072 3.37973 3.03758
2 3.19946 3.72793 3.22612
a b c
0 2.95072 3.37973 3.03758
1 2.95072 3.37973 3.03758
四,Pandas其他方法
1,洗掉(drop)方法
洗掉Series的元素或者DataFrame的某一行(列)的意思,通過物件的方法,洗掉Series的一個元素,
其方法呼叫如下:
def drop(self, labels=None, axis=0, index=None, columns=None,
level=None, inplace=False, errors='raise'):
物件的 .drop(labels, axis=0) 方法回傳的是一個新物件,元物件不會被改變,
1.1 洗掉Series的一個元素
In[11]: ser = Series([4.5,7.2,-5.3,3.6], index=['d','b','a','c'])
In[13]: ser.drop('c')
Out[13]:
d 4.5
b 7.2
a -5.3
dtype: float64
1.2 洗掉DataFrame的行或者列
drop函式默認洗掉行,列需要加axis = 1
In[17]: df = DataFrame(np.arange(9).reshape(3,3), index=['a','c','d'], columns=['oh','te','ca'])
In[18]: df
Out[18]:
oh te ca
a 0 1 2
c 3 4 5
d 6 7 8
In[19]: df.drop('a')
Out[19]:
oh te ca
c 3 4 5
d 6 7 8
In[20]: df.drop(['oh','te'],axis=1)
Out[20]:
ca
a 2
c 5
d 8
1.3 drop函式的inplace引數
采用drop方法,有下面三種等價的運算式
1. DF= DF.drop('column_name', axis=1);
2. DF.drop('column_name',axis=1, inplace=True)
3. DF.drop([DF.columns[[0,1, 3]]], axis=1, inplace=True) # Note: zero indexed
注意:凡是會對原陣列做出修改并回傳一個新陣列的,往往都會有一個inplace可選引數,如果手動設定位True(默認為False),那么原陣列就直接被替換,也就是說,采用inplace = True之后,原陣列名如(情況2 和3 所示)對應的記憶體值直接改變,
而采用inplace =False 之后,原陣列名對應的記憶體值并不改變,需要將新的結果賦給一個新的陣列或者覆寫原陣列的記憶體位置,
1.4 drop函式的使用:資料型別轉換
df['Name'] = df['Name'].astype(np.datetime64)
DataFrame.astype() 方法可對整個DataFrame或某一列進行資料格式轉換,支持Python和NumPy的資料型別,
2,python合并兩個csv檔案(列合并)
注意:要合并的兩個檔案行數需要相同,若不同可指定陣列下標使其相同
代碼如下:
# _*_ coding:utf-8 _*_
import csv
aFile = open('a.csv', 'r')
aInfo = csv.reader(aFile)
bfile = open('b.csv', 'r')
bInfo = csv.reader(bfile)
cfile = open('c.csv', 'w')
abcsv = csv.writer(cfile, dialect='excel')
a=[]
a=list()
b=[]
b=list()
for info in aInfo:
a.append(info)
for info in bInfo:
b.append(info )
for index in range(len(b)):
a[index+1].extend(b[index])
abcsv.writerow(a[index+1])
3,python合并(拼接)多個csv檔案
當做資料分析與挖掘的時候,經常遇到要合并CSV檔案的問題,所以此處記錄一下使用python中的Pandas庫進行拼接,
import pandas as pd
import os
orgin_dir = "Train_A"
result_dir = "result_A"
for filename in os.listdir(orgin_dir):
print(filename)
# header=None表示原始檔案資料沒有列索引,這樣的話read_csv會自動加上列索引
a = pd.read_csv('Train_A/'+filename,header=None)
# header=0表示不保留列名,index=False表示不保留行索引,mode='a'表示附加方式寫入,檔案原有內容不會被清除
a.to_csv('all.csv',mode='a',index=False,header=False)
import pandas as pd
import os
orgin_dir = "Train_A"
result_dir = "result_A"
for filename in os.listdir(orgin_dir):
print(filename)
# header=None表示原始檔案資料沒有列索引,這樣的話read_csv會自動加上列索引
pd.read_csv('Train_A/'+filename,header=None)
# header=0表示不保留列名,index=False表示不保留行索引,mode='a'表示附加方式寫入,檔案原有內容不會被清除
pd.to_csv('all.csv',mode='a',index=False,header=False)
4,排序sort_values 和sort_index
排序是按照某一列的大小進行排序,Python3.x目前提供兩個函式
4.1 sort_index
這個函式似乎不建議使用了,推薦使用sort_values,詳情參考:官方檔案
## 引數
sort_index(axis=0, level=None, ascending=True, inplace=False, kind='quicksort', na_position='last', sort_remaining=True, by=None)
#### 引數說明
axis:0按照行名排序;1按照列名排序
level:默認None,否則按照給定的level順序排列---貌似并不是,檔案
ascending:默認True升序排列;False降序排列
inplace:默認False,否則排序之后的資料直接替換原來的資料框
kind:默認quicksort,排序的方法
na_position:缺失值默認排在最后{"first","last"}
by:按照那一列資料進行排序,但是by引數貌似不建議使用
舉例:
## 對x1列升序排列,x2列升序,處理x1有相同值的情況
import pandas as pd
x = pd.DataFrame({"x1":[1,2,2,3],"x2":[4,3,2,1]})
x.sort_index(by = ["x1","x2"],ascending = [False,True])
4.2 sort_values
## 引數
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
#### 引數說明
axis:{0 or ‘index’, 1 or ‘columns’}, default 0,默認按照索引排序,即縱向排序,如果為1,則是橫向排序
by:str or list of str;如果axis=0,那么by="列名";如果axis=1,那么by="行名";
ascending:布爾型,True則升序,可以是[True,False],即第一欄位升序,第二個降序
inplace:布爾型,是否用排序后的資料框替換現有的資料框
kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’,似乎不用太關心
na_position : {‘first’, ‘last’}, default ‘last’,默認缺失值排在最后面
## 沿著軸方向按指定值排序
x.sort_values(by="x1",ascending= False)
## 沿著行方向按指定行排序
x.sort_values(by = 1,ascending=False,axis=1)
五,Pandas速查手冊(翻譯官網)
此外,在學習的時候,我參考了別人的知乎內容,并查看官網,然后匯總了pandas官網中比較常用的函式和方法,以方便自己記憶,其實這個比較全面的概括了pandas的所有知識點,只不過沒有舉例子,但是要是認真看了我上面的兩個大的例子,學習下面的知識點,根本不費吹灰之力,
1,關鍵縮寫和包的匯入
首先,我們使用如下的縮寫:
df:任意的Pandas DataFrame物件
s:任意的Pandas Series物件
同時匯入pandas包和numpy包
import pandas as pd
import numpy as np
當看到np和pd的時候,我們就知道其是什么含義(這些縮寫都是大家默認的),
2,匯入資料
pd.read_csv(filename):從CSV檔案匯入資料
pd.read_table(filename):從限定分隔符的文本檔案匯入資料
pd.read_excel(filename):從Excel檔案匯入資料
pd.read_sql(query, connection_object):從SQL表/庫匯入資料
pd.read_json(json_string):從JSON格式的字串匯入資料
pd.read_html(url):決議URL、字串或者HTML檔案,抽取其中的tables表格
pd.read_clipboard():從你的粘貼板獲取內容,并傳給read_table()
pd.DataFrame(dict):從字典物件匯入資料,Key是列名,Value是資料
原文:
pd.read_csv(filename) | From a CSV file
pd.read_table(filename) | From a delimited text file (like TSV)
pd.read_excel(filename) | From an Excel file
pd.read_sql(query, connection_object) | Read from a SQL table/database
pd.read_json(json_string) | Read from a JSON formatted string, URL or file.
pd.read_html(url) | Parses an html URL, string or file and extracts tables to a list of dataframes
pd.read_clipboard() | Takes the contents of your clipboard and passes it to read_table()
pd.DataFrame(dict) | From a dict, keys for columns names, values for data as lists
3,匯出資料
df.to_csv(filename):匯出資料到CSV檔案
df.to_excel(filename):匯出資料到Excel檔案
df.to_sql(table_name, connection_object):匯出資料到SQL表
df.to_json(filename):以Json格式匯出資料到文本檔案
原文:
df.to_csv(filename) | Write to a CSV file
df.to_excel(filename) | Write to an Excel file
df.to_sql(table_name, connection_object) | Write to a SQL table
df.to_json(filename) | Write to a file in JSON format
4,創建測驗物件
pd.DataFrame(np.random.rand(20,5)):創建20行5列的隨機陣列成的DataFrame物件
pd.Series(my_list):從可迭代物件my_list創建一個Series物件
df.index = pd.date_range('1900/1/30', periods=df.shape[0]):增加一個日期索引
原文:
pd.DataFrame(np.random.rand(20,5)) | 5 columns and 20 rows of random floats
pd.Series(my_list) | Create a series from an iterable my_list
df.index = pd.date_range('1900/1/30', periods=df.shape[0]) | Add a date index
5,查看,檢查資料
df.head(n):查看DataFrame物件的前n行
df.tail(n):查看DataFrame物件的最后n行
df.shape():查看行數和列數
df.info():查看索引、資料型別和記憶體資訊
df.describe():查看數值型列的匯總統計
s.value_counts(dropna=False):查看Series物件的唯一值和計數
df.apply(pd.Series.value_counts):查看DataFrame物件中每一列的唯一值和計數
原文:
df.head(n) | First n rows of the DataFrame
df.tail(n) | Last n rows of the DataFrame
df.shape | Number of rows and columns
df.info() | Index, Datatype and Memory information
df.describe() | Summary statistics for numerical columns
s.value_counts(dropna=False) | View unique values and counts
df.apply(pd.Series.value_counts) | Unique values and counts for all columns
6,資料選取
df[col]:根據列名,并以Series的形式回傳列
df[[col1, col2]]:以DataFrame形式回傳多列
s.iloc[0]:按位置選取資料
s.loc['index_one']:按索引選取資料
df.iloc[0,:]:回傳第一行
df.iloc[0,0]:回傳第一列的第一個元素
原文:
df[col] | Returns column with label col as Series
df[[col1, col2]] | Returns columns as a new DataFrame
s.iloc[0] | Selection by position
s.loc['index_one'] | Selection by index
df.iloc[0,:] | First row
df.iloc[0,0] | First element of first column
7,資料清理
df.columns = ['a','b','c']:重命名列名
pd.isnull():檢查DataFrame物件中的空值,并回傳一個Boolean陣列
pd.notnull():檢查DataFrame物件中的非空值,并回傳一個Boolean陣列
df.dropna():洗掉所有包含空值的行
df.dropna(axis=1):洗掉所有包含空值的列
df.dropna(axis=1,thresh=n):洗掉所有小于n個非空值的行
df.fillna(x):用x替換DataFrame物件中所有的空值
s.astype(float):將Series中的資料型別更改為float型別
s.replace(1,'one'):用‘one’代替所有等于1的值
s.replace([1,3],['one','three']):用'one'代替1,用'three'代替3
df.rename(columns=lambda x: x + 1):批量更改列名
df.rename(columns={'old_name': 'new_ name'}):選擇性更改列名
df.set_index('column_one'):更改索引列
df.rename(index=lambda x: x + 1):批量重命名索引
原文:
df.columns = ['a','b','c'] | Rename columns
pd.isnull() | Checks for null Values, Returns Boolean Arrray
pd.notnull() | Opposite of pd.isnull()
df.dropna() | Drop all rows that contain null values
df.dropna(axis=1) | Drop all columns that contain null values
df.dropna(axis=1,thresh=n) | Drop all rows have have less than n non null values
df.fillna(x) | Replace all null values with x
s.fillna(s.mean()) | Replace all null values with the mean (mean can be replaced with almost any function from the statistics section)
s.astype(float) | Convert the datatype of the series to float
s.replace(1,'one') | Replace all values equal to 1 with 'one'
s.replace([1,3],['one','three']) | Replace all 1 with 'one' and 3 with 'three'
df.rename(columns=lambda x: x + 1) | Mass renaming of columns
df.rename(columns={'old_name': 'new_ name'}) | Selective renaming
df.set_index('column_one') | Change the index
df.rename(index=lambda x: x + 1) | Mass renaming of index
8,資料處理:Filter,Sort和GroupBy
df[df[col] > 0.5]:選擇col列的值大于0.5的行
df.sort_values(col1):按照列col1排序資料,默認升序排列
df.sort_values(col2, ascending=False):按照列col1降序排列資料
df.sort_values([col1,col2], ascending=[True,False]):先按列col1升序排列,后按col2降序排列資料
df.groupby(col):回傳一個按列col進行分組的Groupby物件
df.groupby([col1,col2]):回傳一個按多列進行分組的Groupby物件
df.groupby(col1)[col2]:回傳按列col1進行分組后,列col2的均值
df.pivot_table(index=col1, values=[col2,col3], aggfunc=max):創建一個按列col1進行分組,并計算col2和col3的最大值的資料透視表
df.groupby(col1).agg(np.mean):回傳按列col1分組的所有列的均值
data.apply(np.mean):對DataFrame中的每一列應用函式np.mean
data.apply(np.max,axis=1):對DataFrame中的每一行應用函式np.max
原文:
df[df[col] > 0.5] | Rows where the column col is greater than 0.5
df[(df[col] > 0.5) & (df[col] < 0.7)] | Rows where 0.7 > col > 0.5
df.sort_values(col1) | Sort values by col1 in ascending order
df.sort_values(col2,ascending=False) | Sort values by col2 in descending order
df.sort_values([col1,col2],ascending=[True,False]) | Sort values by col1 in ascending order then col2 in descending order
df.groupby(col) | Returns a groupby object for values from one column
df.groupby([col1,col2]) | Returns groupby object for values from multiple columns
df.groupby(col1)[col2] | Returns the mean of the values in col2, grouped by the values in col1 (mean can be replaced with almost any function from the statistics section)
df.pivot_table(index=col1,values=[col2,col3],aggfunc=mean) | Create a pivot table that groups by col1 and calculates the mean of col2 and col3
df.groupby(col1).agg(np.mean) | Find the average across all columns for every unique col1 group
df.apply(np.mean) | Apply the function np.mean() across each column
nf.apply(np.max,axis=1) | Apply the function np.max() across each row
9,資料合并
df1.append(df2):將df2中的行添加到df1的尾部
df.concat([df1, df2],axis=1):將df2中的列添加到df1的尾部
df1.join(df2,on=col1,how='inner'):對df1的列和df2的列執行SQL形式的join
原文:
df1.append(df2) | Add the rows in df1 to the end of df2 (columns should be identical)
pd.concat([df1, df2],axis=1) | Add the columns in df1 to the end of df2 (rows should be identical)
df1.join(df2,on=col1,how='inner') | SQL-style join the columns in df1 with the columns on df2 where the rows for col have identical values. how can be one of 'left', 'right', 'outer', 'inner'
10,資料統計
df.describe():查看資料值列的匯總統計
df.mean():回傳所有列的均值
df.corr():回傳列與列之間的相關系數
df.count():回傳每一列中的非空值的個數
df.max():回傳每一列的最大值
df.min():回傳每一列的最小值
df.median():回傳每一列的中位數
df.std():回傳每一列的標準差
原文:
df.describe() | Summary statistics for numerical columns
df.mean() | Returns the mean of all columns
df.corr() | Returns the correlation between columns in a DataFrame
df.count() | Returns the number of non-null values in each DataFrame column
df.max() | Returns the highest value in each column
df.min() | Returns the lowest value in each column
df.median() | Returns the median of each column
df.std() | Returns the standard deviation of each column
作者:戰爭熱誠
https://www.cnblogs.com/wj-1314/p/9997131.html
參考http://wiki.jikexueyuan.com/project/start-learning-python/311.html
https://zhuanlan.zhihu.com/p/25630700
https://www.dataquest.io/blog/pandas-cheat-sheet/
< END >
程式員單詞庫
http://dida100.com/it/#/listw
長按2秒學單詞學代碼
推薦閱讀 點擊標題可跳轉
可能是最全的NumPy基礎知識
Python 3 入門,看這篇就夠了
面個試,把公司的底褲扒了~
值得學習練手的22個Python迷你程式(附代碼)
漫畫:假如c語言是虛竹,java是喬峰,python是段譽,你拜誰為師?
![]() | 👈長按左側二維碼(非本號) 回復專案70個python練手案例 回復二級計算機二級資料 |
有用就獎勵個👍和在看唄~
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/301423.html
標籤:AI
上一篇:機器學習基礎一站通

