資料分析面試準備(待更)
目錄:
一.python如何安裝第三方包
二.Numpy的語法
三.Pandas的語法
四.Matplotlib的語法
五.Sklearn的語法
六.大資料元件的知識
七.Linux的基本命令
八.Excel
九.SQL
十.統計概率
十一.機器學習
十二.python中函式的引數
一.python如何安裝第三方包
import numpy as np
1.pycharm中以點選的方式安裝
2.Anaconda環境下,先conda create建立虛擬環境,再activate啟用虛擬環境,為了更安全。在其中pip install。在此過程中可以配置清華映象,使下載速度加快
3.如果第二種方式失敗,可能由於網路或者包的問題,就上網將包下載到本地,然後pip install 【路徑/檔案】即可
二.Numpy的語法
參考https://www.jianshu.com/p/a260a8c43e44
1 程式碼示例: 2 >>> import numpy as np 3 >>> a = np.arange(15).reshape(3,5) 4 >>> a 5 array([[ 0, 1, 2, 3, 4], 6 [ 5, 6, 7, 8, 9], 7 [10, 11, 12, 13, 14]])8 >>> a.shape 9 (3, 5) 10 >>> a.ndim 11 2 12 >>> a.dtype.name 13 'int64' 14 >>> a.dtype 15 dtype('int64') 16 >>> a.size 17 15 18 >>> a.itemsize#表示陣列中每個元素的位元組大小。 19 8 20 >>> type(a) 21 <class 'numpy.ndarray'> 22 >>> 23 >>> b = np.array([1,2,3,4,5,6,7,8,9])24 >>> b 25 array([1, 2, 3, 4, 5, 6, 7, 8, 9]) 26 >>> c = np.array([1,2,3,4,5,6,'7','a','b']) 27 >>> c 28 array(['1', '2', '3', '4', '5', '6', '7', 'a', 'b'], dtype='<U21') 29 >>> type(b) 30 <class 'numpy.ndarray'> 31 >>> type(c) 32 <class 'numpy.ndarray'> 33 >>> c.dtype#ndarray.dtype用來描述陣列中元素的型別,ndarray中的所有元素都必須是同一種類型,如果在構造陣列時,
傳入的引數不是同一型別的,不同的型別將進行統一轉化。除了標準的Python型別外,
NumPy額外提供了一些自有的型別,如numpy.int32、numpy.int16以及numpy.float64等
34 dtype('<U21') 35 >>> b.dtype 36 dtype('int64') 37 >>> c.itemsize 38 84 39 >>> b.itemsize 40 8
1 #NumPy中建立陣列的方式有若干種。最簡單的,可以直接利用Python中常規的list和tuple進行建立。 2 >>> import numpy as np 3 >>> a = np.array([1,2,3,4,5,6]) 4 >>> b = np.array((1,2,3,4,5,6)) 5 >>> a 6 array([1, 2, 3, 4, 5, 6]) 7 >>> b 8 array([1, 2, 3, 4, 5, 6])
1 >>> import numpy as np 2 >>> a = np.array([[1,2,3],[2,3,4]]) 3 >>> a 4 array([[1, 2, 3], 5 [2, 3, 4]]) 6 >>> b = np.array([[1,2,3],[2,3,4],[3,4,5]]) 7 >>> b 8 array([[1, 2, 3], 9 [2, 3, 4], 10 [3, 4, 5]])
1 #建立陣列的時候,可以明確的規定陣列的型別。 2 >>> c = np.array([1,2,3], dtype = complex) 3 >>> c 4 array([1.+0.j, 2.+0.j, 3.+0.j]) 5 >>> d = np.array([[1,2,3],[4,5,6]], dtype = '<U1') 6 >>> d 7 array([['1', '2', '3'], 8 ['4', '5', '6']], dtype='<U1')
1 >>> import numpy as np 2 >>> a = np.zeros((3,4)) 3 >>> a 4 array([[0., 0., 0., 0.], 5 [0., 0., 0., 0.], 6 [0., 0., 0., 0.]]) 7 >>> b = np.zeros((2,2,2)) 8 >>> b 9 array([[[0., 0.], 10 [0., 0.]], 11 12 [[0., 0.], 13 [0., 0.]]]) 14 >>> c = np.ones((3,3)) 15 >>> c 16 array([[1., 1., 1.], 17 [1., 1., 1.], 18 [1., 1., 1.]]) 19 >>> d = np.ones((3,3), dtype = np.int16) 20 >>> d 21 array([[1, 1, 1], 22 [1, 1, 1], 23 [1, 1, 1]], dtype=int16) 24 >>> e = np.arange(15) 25 >>> e 26 array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) 27 >>> f = np.arange(15).reshape(3,5) 28 >>> f 29 array([[ 0, 1, 2, 3, 4], 30 [ 5, 6, 7, 8, 9], 31 [10, 11, 12, 13, 14]]) 32 >>> g = np.arange(0,15,3) 33 >>> g 34 array([ 0, 3, 6, 9, 12]) 35 >>> h = np.arange(0,3,0.3) 36 >>> h 37 array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8, 2.1, 2.4, 2.7]) 38 39 >>> from numpy import pi 40 >>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2 41 array([ 0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ]) 42 >>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points 43 >>> f = np.sin(x)
1 >>> import numpy as np 2 >>> a = np.array([10,20,30,40]) 3 >>> b = np.arange(4) 4 >>> a 5 array([10, 20, 30, 40]) 6 >>> b 7 array([0, 1, 2, 3]) 8 >>> c = a - b 9 >>> c 10 array([10, 19, 28, 37]) 11 >>> a 12 array([10, 20, 30, 40]) 13 >>> b 14 array([0, 1, 2, 3]) 15 >>> b**2 16 array([0, 1, 4, 9]) 17 >>> b 18 array([0, 1, 2, 3]) 19 >>> a<35 20 array([ True, True, True, False]) 21 >>> a 22 array([10, 20, 30, 40])
1 #在NumPy中,*用於陣列間元素對應的乘法,而不是矩陣乘法,矩陣乘法可以用dot()方法來實現。 2 >>> A = np.array([[1,2],[3,4]]) 3 >>> B = np.array([[0,1],[0,1]]) 4 >>> A 5 array([[1, 2], 6 [3, 4]]) 7 >>> B 8 array([[0, 1], 9 [0, 1]]) 10 >>> A*B # elementwise product 11 array([[0, 2], 12 [0, 4]]) 13 >>> A.dot(B) # matrix product 14 array([[0, 3], 15 [0, 7]]) 16 >>> np.dot(A,B) # another matrix product 17 array([[0, 3], 18 [0, 7]])
1 >>> a = np.random.random((2,3)) 2 >>> a 3 array([[0.62181697, 0.26165654, 0.34994938], 4 [0.95619296, 0.24614291, 0.42120462]]) 5 >>> a.sum() 6 2.8569633678947346 7 >>> a.min() 8 0.24614290611891454 9 >>> a.max() 10 0.9561929625193091
1 >>> b = np.arange(12).reshape(3,4) 2 >>> b 3 array([[ 0, 1, 2, 3], 4 [ 4, 5, 6, 7], 5 [ 8, 9, 10, 11]]) 6 >>> b.sum(axis = 0) # sum of each column 7 array([12, 15, 18, 21]) 8 >>> b.sum(axis = 1) # sum of each row 9 array([ 6, 22, 38]) 10 >>> b.min(axis = 0) # min of each column 11 array([0, 1, 2, 3]) 12 >>> b.min(axis = 1) # min of each row 13 array([0, 4, 8]) 14 >>> b.max(axis = 0) # max of each column 15 array([ 8, 9, 10, 11]) 16 >>> b.max(axis = 1) # max of each row 17 array([ 3, 7, 11]) 18 >>> b.cumsum(axis = 1) # cumulative sum along each row 19 array([[ 0, 1, 3, 6], 20 [ 4, 9, 15, 22], 21 [ 8, 17, 27, 38]]) 22 >>> b.cumsum(axis = 0) # cumulative sum along each column 23 array([[ 0, 1, 2, 3], 24 [ 4, 6, 8, 10], 25 [12, 15, 18, 21]])
1 >>> a = np.arange(10)**3 2 >>> a 3 array([ 0, 1, 8, 27, 64, 125, 216, 343, 512, 729]) 4 >>> a[3] 5 27 6 >>> a[2:5] 7 array([ 8, 27, 64]) 8 >>> a[:6:2] = -1111 9 >>> a 10 array([-1111, 1, -1111, 27, -1111, 125, 216, 343, 512, 11 729]) 12 >>> a[::-1]#倒序 13 array([ 729, 512, 343, 216, 125, -1111, 27, -1111, 1, 14 -1111])
1 >>>b = np.arange(15).reshape(3,5) 2 >>>for element in b.flat:#flat屬性是array中的每個元素的迭代器。 3 >>> print(element) 4 0 5 1 6 2 7 3 8 4 9 5 10 6 11 7 12 8 13 9 14 10 15 11 16 12 17 13 18 14
1 >>> import numpy as np 2 >>> a = np.ones((3,4), dtype = int) 3 >>> a 4 array([[1, 1, 1, 1], 5 [1, 1, 1, 1], 6 [1, 1, 1, 1]]) 7 >>> a.ravel() 8 array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) 9 >>> a 10 array([[1, 1, 1, 1], 11 [1, 1, 1, 1], 12 [1, 1, 1, 1]]) 13 >>> b = a.ravel() 14 >>> b 15 array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]) 16 >>> a 17 array([[1, 1, 1, 1], 18 [1, 1, 1, 1], 19 [1, 1, 1, 1]]) 20 >>> c = a.reshape(2,-1)#除此之外,NumPy還提供了可以直接修改原始陣列shape的方法——resize()
。resize()
方法和reshape()
方法的最主要區別在於,reshape()
方法返回一個特定shape的陣列,而resize()
方法會直接更改原陣列。 21 >>> c 22 array([[1, 1, 1, 1, 1, 1], 23 [1, 1, 1, 1, 1, 1]]) 24 >>> a 25 array([[1, 1, 1, 1], 26 [1, 1, 1, 1], 27 [1, 1, 1, 1]]) 28 >>> a.T 29 array([[1, 1, 1], 30 [1, 1, 1], 31 [1, 1, 1], 32 [1, 1, 1]]) 33 >>> a 34 array([[1, 1, 1, 1], 35 [1, 1, 1, 1], 36 [1, 1, 1, 1]]) 37 >>> d = a.T 38 >>> d 39 array([[1, 1, 1], 40 [1, 1, 1], 41 [1, 1, 1], 42 [1, 1, 1]]) 43 >>> a.shape 44 (3, 4) 45 >>> b.shape 46 (12,) 47 >>> c.shape 48 (2, 6) 49 >>> d.shape 50 (4, 3)
1 #hstack()實現陣列橫向堆疊,vstack()實現陣列縱向堆疊。 2 >>> a = np.floor(10*np.random.random((2,2))) 3 >>> a 4 array([[0., 8.], 5 [4., 8.]]) 6 >>> b = np.floor(10*np.random.random((2,2))) 7 >>> b 8 array([[1., 4.], 9 [4., 1.]]) 10 >>> np.vstack((a,b)) 11 array([[0., 8.], 12 [4., 8.], 13 [1., 4.], 14 [4., 1.]]) 15 >>> np.hstack((a,b)) 16 array([[0., 8., 1., 4.], 17 [4., 8., 4., 1.]])
1 >>> a = np.arange(12).reshape(3,4) 2 >>> a 3 array([[ 0, 1, 2, 3], 4 [ 4, 5, 6, 7], 5 [ 8, 9, 10, 11]]) 6 >>> np.split(a,3) 7 [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])] 8 >>> np.h 9 np.half( np.hanning( np.histogram( np.histogramdd( np.hstack( 10 np.hamming( np.heaviside( np.histogram2d( np.hsplit( np.hypot( 11 >>> np.hsplit(a,4) 12 [array([[0], 13 [4], 14 [8]]), array([[1], 15 [5], 16 [9]]), array([[ 2], 17 [ 6], 18 [10]]), array([[ 3], 19 [ 7], 20 [11]])] 21 >>> np.vsplit(a,3) 22 [array([[0, 1, 2, 3]]), array([[4, 5, 6, 7]]), array([[ 8, 9, 10, 11]])]
- NumPy中,陣列的複製有三種方式:
- Python通用的地址複製:通過 b = a 複製 a 的值,b 與 a 指向同一地址,改變 b 同時也改變 a。d=a
- 通過檢視
ndarray.view()
僅複製值,當對 c 值進行改變會改變 a 的對應的值,而改變 c 的 shape 不改變 a 的 shape。d = a.view() ndarray.copy()
進行的完整的拷貝,產生一份完全相同的獨立的複製。d = a.copy()
三.Pandas的語法
1 # 一般以pd作為pandas的縮寫 2 import pandas as pd 3 4 # 讀取檔案 5 df = pd.read_csv('file.csv') 6 7 # 返回資料的大小 8 df.shape 9 10 # 顯示資料的一些物件資訊和記憶體使用 11 df.info() 12 13 # 顯示資料的統計量資訊 14 df.describe()
1 data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'], 2 'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3], 3 'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1], 4 'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']} 5 6 labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'] 7 8 df = pd.DataFrame(data, index=labels) 9 df[['age', 'animal']] 10 df[[0,1]] 11 #以上兩種表達方式等價 12 13 #位置索引 14 df.iloc[0:2, 0:2] 15 #loc與iloc的主要區別就是索引要用標籤不能用序號 16 df.loc[['a', 'b'], ['animal', 'age']] 17 #ix可以用位置索引和標籤索引的混合使用方式 18 df.ix[0:2, ['animal', 'age']] 19 #條件索引 20 df[(df['animal'] == 'cat') & (df['age'] < 3)] 21 #找到缺失值 22 df[df['age'].isnull()] 23 #填充缺失值 24 df['age'].fillna(0, inplace=True) 25 #將字元值替換成布林值 26 df['priority'] = df['priority'].map({'yes': True, 'no': False})
from pandas import Series,DataFrame #資料結構:Series和DataFrame。Series是一種類似於以為NumPy陣列的物件,它由一組資料(各種NumPy資料型別)和與之相關的一組資料標籤(即索引)組成的。可以用index和values分別規定索引和值。如果不規定索引,會自動建立 0 到 N-1 索引。 #Series可以設定index,有點像字典,用index索引 obj = Series([1,2,3],index=['a','b','c']) #print obj['a'] #也就是說,可以用字典直接建立Series dic = dict(key = ['a','b','c'],value = [1,2,3]) dic = Series(dic) #下面注意可以利用一個字串更新鍵值 key1 = ['a','w','e'] #注意下面的語句可以將 Series 物件中的值提取出來,不過要知道的字典是不能這麼做提取的 dic1 = Series(obj,index = key1) obj = Series([1,2,3,4],index=['a','b','c','d']) frame = DataFrame(np.arange(9).reshape((3,3)),index = ['a','c','d'],columns = ['Ohio','Texas','California']) #Series切片和索引 #print obj[obj < 2] #注意:利用標籤的切片與python的切片不同,兩端都是包含的(有道理) print obj['b':'c'] #對於DataFrame,列可以直接用名稱 print frame['Ohio'] #特殊情況:通過切片和bool型索引,得到的是行(有道理) print frame[:2] print frame[frame['Ohio'] != 0] #下面的方式是對frame所有元素都適用,不是行或者列,下面的得到的是numpy.ndarray型別的資料 print frame[frame < 5],type(frame[frame < 5]) frame[frame < 5] = 0 print frame #對於DataFrame上的標籤索引,用ix進行 print frame.ix[['a','d'],['Ohio','Texas']] print frame.ix[2] #注意這裡預設取行 #注意下面預設取行 print frame.ix[frame.Ohio > 0] #注意下面的逗號後面是列標 print frame.ix[frame.Ohio > 0,:2]
1 df.agg({'ext price': ['sum', 'mean'], 2 'quantity': ['sum', 'mean'], 3 'unit price': ['mean'], 4 'sku': [get_max]})
1 import pandas as pd 2 df1 = pd.DataFrame([[1,2,3],[5,6,7],[3,9,0],[8,0,3]],columns=['x1','x2','x3']) 3 df2 = pd.DataFrame([[1,2],[4,6],[3,9]],columns=['x1','x4']) 4 print (df1) 5 print (df2) 6 df3 = pd.merge(df1,df2,how = 'left',on='x1') 7 print (df3) 8 df4 = pd.merge(df1,df2,how = 'right',on='x1') 9 print (df4) 10 df5 = pd.merge(df1,df2,how = 'inner',on='x1') 11 print (df5) 12 df6 = pd.merge(df1,df2,how = 'outer',on='x1') 13 print (df6)
四.Matplotlib的語法
參考:https://blog.csdn.net/Notzuonotdied/article/details/77876080
1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 # 從[-1,1]中等距去50個數作為x的取值 5 x = np.linspace(-10, 10, 5000) 6 #print(x) 7 y = sin(x) 8 # 第一個是橫座標的值,第二個是縱座標的值 9 plt.plot(x, y) 10 # 必要方法,用於將設定好的figure物件顯示出來
1 import matplotlib.pyplot as plt 2 import numpy as np 3 4 # 多個figure 5 x = np.linspace(-1, 1, 50) 6 y1 = 2*x + 1 7 y2 = 2**x + 1 8 9 # 使用figure()函式重新申請一個figure物件 10 # 注意,每次呼叫figure的時候都會重新申請一個figure物件 11 plt.figure() 12 # 第一個是橫座標的值,第二個是縱座標的值 13 plt.plot(x, y1) 14 15 # 第一個引數表示的是編號,第二個表示的是圖表的長寬 16 plt.figure(num = 3, figsize=(8, 5)) 17 # 當我們需要在畫板中繪製兩條線的時候,可以使用下面的方法: 18 plt.plot(x, y2) 19 plt.plot(x, y1, 20 color='red', # 線顏色 21 linewidth=1.0, # 線寬 22 linestyle='--' # 線樣式 23 )
1 # 設定軸線的lable(標籤) 2 plt.xlabel("I am x") 3 plt.ylabel("I am y") 4 5 plt.xticks(())#隱藏橫縱座標 6 plt.yticks(())# 7 8 plt.scatter()#散點圖 9 plt.bar()#條形圖 10 plt.contourf()#等高線圖 11 plt.imshow()#顯示圖片
五.Sklearn的語法
1 model.fit(X_train,Y_train)#訓練 2 model.predict(X_test)#測試
六.大資料元件的知識
七.Linux的基本命令
八.Excel
九.SQL
十.統計概率
十一.機器學習
十二.python中函式的引數
必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數
必選引數:
1 def power(x, n): 2 s = 1 3 while n > 0: 4 n = n - 1 5 s = s * x 6 return s
呼叫時如果傳入的引數少了一個就會報錯,所以x和n都是必選引數。
預設引數:
1 def power(x, n=2): 2 s = 1 3 while n > 0: 4 n = n - 1 5 s = s * x 6 return s 7 8 >>> power(5) 9 25 10 >>> power(5, 2) 11 25
可變引數
由於引數個數不確定,我們首先想到可以把a,b,c……作為一個list或tuple傳進來,這樣,函式可以定義如下:
1 def calc(numbers): 2 sum = 0 3 for n in numbers: 4 sum = sum + n * n 5 return sum 6 7 #但是呼叫的時候,需要先組裝出一個list或tuple: 8 >>> calc([1, 2, 3]) 9 14 10 >>> calc((1, 3, 5, 7)) 11 84
定義可變引數和定義一個list或tuple引數相比,僅僅在引數前面加了一個*
號。在函式內部,引數numbers
接收到的是一個tuple,因此,函式程式碼完全不變。但是,呼叫該函式時,可以傳入任意個引數,包括0個引數:
1 def calc(*numbers): 2 sum = 0 3 for n in numbers: 4 sum = sum + n * n 5 return sum 6 7 >>> calc(1, 2) 8 5 9 >>> calc() 10 0 11 >>> calc(1, 2, 3) 12 14 13 >>> calc(1, 3, 5, 7) 14 84
Python允許你在list或tuple前面加一個*
號,把list或tuple的元素變成可變引數傳進去:
>>> nums = [1, 2, 3] >>> calc(*nums) 14 #*nums表示把nums這個list的所有元素作為可變引數傳進去。這種寫法相當有用,而且很常見。
命名關鍵字引數
如果要限制關鍵字引數的名字,就可以用命名關鍵字引數,例如,只接收city
和job
作為關鍵字引數。這種方式定義的函式如下:
1 def person(name, age, *, city, job): 2 print(name, age, city, job)
和關鍵字引數**kw
不同,命名關鍵字引數需要一個特殊分隔符*
,*
後面的引數被視為命名關鍵字引數。
1 >>> person('Jack', 24, city='Beijing', job='Engineer') 2 Jack 24 Beijing Engineer 3 4 #如果函式定義中已經有了一個可變引數,後面跟著的命名關鍵字引數就不再需要一個特殊分隔符*了: 5 def person(name, age, *args, city, job): 6 print(name, age, args, city, job) 7 8 #命名關鍵字引數必須傳入引數名,這和位置引數不同。如果沒有傳入引數名,呼叫將報錯 9 >>> person('Jack', 24, 'Beijing', 'Engineer') 10 Traceback (most recent call last): 11 File "<stdin>", line 1, in <module> 12 TypeError: person() takes 2 positional arguments but 4 were given 13 #由於呼叫時缺少引數名city和job,Python直譯器把這4個引數均視為位置引數,但person()函式僅接受2個位置引數。 14 15 #命名關鍵字引數可以有預設值,從而簡化呼叫 16 #使用命名關鍵字引數時,要特別注意,如果沒有可變引數,就必須加一個*作為特殊分隔符。如果缺少*,Python直譯器將無法識別位置引數和命名關鍵字引數 17 18 #在Python中定義函式,可以用必選引數、預設引數、可變引數、關鍵字引數和命名關鍵字引數,這5種引數都可以組合使用。但是請注意,引數定義的順序必須是:必選引數、預設引數、可變引數、命名關鍵字引數和關鍵字引數。
關鍵字引數
關鍵字引數允許你傳入0個或任意個含引數名的引數,這些關鍵字引數在函式內部自動組裝為一個dict。
1 def person(name, age, **kw): 2 print('name:', name, 'age:', age, 'other:', kw) 3 4 >>> person('Bob', 35, city='Beijing') 5 name: Bob age: 35 other: {'city': 'Beijing'} 6 >>> person('Adam', 45, gender='M', job='Engineer') 7 name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'} 8 9 >>> extra = {'city': 'Beijing', 'job': 'Engineer'} 10 >>> person('Jack', 24, city=extra['city'], job=extra['job']) 11 name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'} 12 13 >>> extra = {'city': 'Beijing', 'job': 'Engineer'} 14 >>> person('Jack', 24, **extra) 15 name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
python連線資料庫
1 import pymysql 2 import pandas as pd 3 import numpy as np 4 from get_a import * 5 from connect import * 6 7 #連線資料庫,將資料匯入dataframe 8 db = pymysql.connect("localhost", "root", "yuanxu135689", "mytrip") 9 cursor = db.cursor() 10 sql ="SELECT record_time,max(vehicle_speed),engine_rpm FROM TB_IOV_DEVICE_OBD_41030402427 where device_id='%s' GROUP BY record_time" % (41030402427) 11 dbdata = read_table(cursor, sql) 12 db.close() 13 dbdata.columns = ['time', 'speed', 'rpm']