python及pandas,numpy等知識點技巧點學習筆記

世有因果知因求果發表於2017-09-11

python和java,.net,php web平臺互動最好使用web通訊方式,不要使用Jypython,IronPython,這樣的好處是能夠保持程式模組化,解耦性好

python允許使用'''...'''方式來表示多行程式碼:

>>> print(r'''Hello,
... Lisa!''')
Hello,
Lisa!
>>>

 

>>> print('''line1
... line2
... line3''')
line1
line2
line3

也可以使用r' xxx  '表示xxx內部不做任何轉義操作,對於原生輸出內容有益

print(r'\\\t\\')
# 輸出 \\\t\\

python能夠直接處理的資料型別:

整數,浮點數,字串,布林值(True,False),

還有list(類似陣列),dict(類似js object literal)

常量: PI

兩種除法:

/ : 自動使用浮點數,比如10/3=3.33333 9/3=3.0

// : 取整   10//3= 3

%: 10%3=1

注意:

python支援多種資料型別,而在計算機內部,可以把任何資料都看成一個"物件“,而變數就是在程式中用來指向這些資料物件的,對變數賦值實際上就是把資料和變數給關聯起來

python的整數沒有大小的限制

python字串編碼常用的函式:

ord(‘x’)返回x字元對應的unicode編碼,chr(‘hexcode’)則返回unicode編碼對應的祖父

>>> ord('A')
65
>>> ord('')
20013
>>> chr(66)
'B'
>>> chr(25991)
''

 由於python的字串型別是str,在記憶體中以unicode表示,一個字元都會對應著若干個位元組,但是如果要在網路上傳輸,或者儲存到磁碟上,則需要把str變為以位元組為單位的bytes型別。

python對bytes型別的資料用帶b字首的單引號或者雙引號表示:

>>> 'ABC'.encode('ascii')
b'ABC'
>>> '中文'.encode('utf-8')
b'\xe4\xb8\xad\xe6\x96\x87'

反過來,如果從網路或者磁碟上讀取了utf-8 byte位元組流,那麼必須做decode操作成為unicode後才能在程式碼中使用,需要使用decode方法:

>>> b'ABC'.decode('ascii')
'ABC'
>>> b'\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8')
'中文'

>>> len('abc')
3
>>> len('')
1
>>> len('中文'.encode('utf-8'))
6

Python直譯器讀取原始碼時,為了讓它按UTF-8編碼讀取,我們通常在檔案開頭寫上這兩行:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

所有python中需要顯示的字串,應該以 u"this is unicode字串"的方式來定義使用字串

字串的格式化輸出:

>>> 'Hello, %s' % 'world'
'Hello, world'
>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)
'Hi, Michael, you have $1000000.'

list型別資料

list類似於js的array,是一種有序的集合,可以隨時新增和刪除對應的元素

>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates
['Michael', 'Bob', 'Tracy']
>>> len(classmates)
3
>>> classmates[0]
'Michael'
>>> classmates[1]
'Bob'
>>> classmates[2]
'Tracy'
>>> classmates[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> classmates[-1]
'Tracy'
>>> classmates[-2]
'Bob'
>>> classmates[-3]
'Michael'
>>> classmates[-4]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range

 list還有以下常用的操作函式: append,insert,pop

list列表生成式

L = ['Hello', 'World', 18, 'Apple', None]
print([s.lower() if isinstance(s,str) else s for s in  L])
['hello', 'world', 18, 'apple', None]

generator生成式

在科學計算中,如果range為百萬,我們沒有必要全部先在記憶體中以list形式生成好,只需在用到的時候再生成,這就是generator,generator本身儲存的是演算法,generator本身也是iteratable可遞迴訪問的(用在for迴圈中)

>>> L = [x * x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x * x for x in range(10))
>>> g
<generator object <genexpr> at 0x1022ef630>
>>> next(g)
0
>>> next(g)
1
>>> next(g)
4
>>> next(g)
9
>>> next(g)
16
>>> g = (x * x for x in range(10))
>>> for n in g:
... print(n)
...
0
1
4
9

如果是複雜的generator演算法邏輯,則可以通過類似函式來定義。

相對比較複雜的generator

gougu = {z: (x,y) for z in [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] for y in range(1, z) for x in range(1, y) if x*x + y*y == z*z}

gougu
Out[17]: 
{5: (3, 4),
 10: (6, 8),
 13: (5, 12),
 15: (9, 12),
 17: (8, 15),
 20: (12, 16),
 25: (7, 24),
 26: (10, 24)}
gougu = [[x, y, z] for z in [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] for y in range(1, z) for x in range(1, y) if x*x + y*y == z*z]
gougu
Out[19]: 
[[3, 4, 5],
 [6, 8, 10],
 [5, 12, 13],
 [9, 12, 15],

pyt = ((x, y, z) for z in [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] for y in range(1, z) for x in range(1, y) if x*x + y*y == z*z)
#這裡pyt就是一個generator,注意最外面的括號!隨後可以使用for來呼叫生成式
print([m for m in pyt])
[(3, 4, 5), (6, 8, 10), (5, 12, 13), (9, 12, 15), (8, 15, 17), (12, 16, 20), (15, 20, 25), (7, 24, 25), (10, 24, 26)]

 

import jieba
documents = [u'我來到北京清華大學',
             u'假如當前的單詞表有10個不同的單詞',
             u'我是中華人民共和國的公民,來自上海,老家是湖北襄陽']

documents_after = []
documents_after = [[w for w in jieba.cut(s)] for s in documents]
documents_after2 = [' '.join(s) for s in documents_after]
print(documents_after)
print(documents_after2)
[['', '來到', '北京', '清華大學'], ['假如', '當前', '', '單詞表', '', '10', '', '不同', '', '單詞'], ['', '', '中華人民共和國', '', '公民', '', '來自', '上海', '', '老家', '', '湖北', '襄陽']]
['我 來到 北京 清華大學', '假如 當前 的 單詞表 有 10 個 不同 的 單詞', '我 是 中華人民共和國 的 公民 , 來自 上海 , 老家 是 湖北 襄陽']

 

generator(yield)函式:

def fib(max):
    n,a,b = 0,0,1
    while n < max:
        yield b
        a,b = b,a+b
        n = n+1
    return  'done'
f = fib(6)
for n in fib(6):
    print(n)

1
1
2
3
5
8

Generator in-depth

generator是一個產生一系列結果的一個函式(注意不是隻產生一個value的函式哦!)

def countdown(n):
    print("counting down from ",n)
    while n > 0:
        yield n
        n -=1
x = countdown(10)
print(x)
# 注意並未列印出 counting down from 10的資訊哦
<generator object countdown at 0x0000026385694468>

print(x.__next__())
# counting down from  10
# 10
print(x.__next__())
#Out[17]:
#9

generator和普通函式的行為是完全不同的。呼叫一個generator functionjiang chuangjian yige generator object.但是注意這時並不會呼叫函式本身!!

當generator return時,iteration就將stop.

當呼叫__next__()時yield一個value出來,但是並不會繼續往下執行,function掛起pending,直到下一次next()呼叫時才往下執行,但是卻記錄著相應的狀態.

generator雖然行為和iterator非常類似,但是也有一點差別:generator是一個one-time operation

generator還有一個無與倫比的優點:由於generator並不會一次性把所有序列載入到記憶體處理後返回,而是一輪一輪地載入一輪一輪地處理並返回,因此再大的檔案,generator也可以處理!

generator expression

a = [1,2,3,4]
b = (2*x for x in a)
b
Out[19]: 
<generator object <genexpr> at 0x0000023EDA2C6CA8>
for i in b:
    print(i)
2
4
6
8

generator表示式語法:

(expression for i in s if condition)
# 等價於
for i in s:
    if condition:
        yield expression

注意:如果generator expression僅僅用於作為唯一的函式形參時,可以省略()

a = [1,2,3,4]
sum(x*x for x in a)
Out[21]: 
30

 

迭代器iterator

我們知道可以用於for迴圈中不斷迭代的資料有:list,tuple,dict,set,str等集合類資料型別,或者是generator(包括帶yield的generator function)。所有這些型別的資料我們都稱之為可迭代的資料型別(iterable),可以使用isinstance()來具體判斷:

>>> from collections import Iterable
>>> isinstance([], Iterable)
True
>>> isinstance({}, Iterable)
True
>>> isinstance('abc', Iterable)
True
>>> isinstance((x for x in range(10)), Iterable)
True
>>> isinstance(100, Iterable)
False

而generator不僅可以用於for迴圈,還可以被next()函式所呼叫,並且返回下一個值,直到丟擲StopIteration異常。

所有可以被next()函式呼叫並不斷返回下一個值的物件成為迭代器Iterator

同樣可以使用isinstance()來判斷是否Iterator物件:

>>> from collections import Iterator
>>> isinstance((x for x in range(10)), Iterator)
True
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('abc', Iterator)
False

從上面可以看到,雖然list,dict,set,str是Iterable,但是卻不是Iterator,而generator是Iterator

但是我們可以通過iter()函式將dist,list等iterable物件轉變為iterator,比如:

>>> isinstance(iter([]), Iterator)
True
>>> isinstance(iter('abc'), Iterator)
True

iterable小結

凡是可作用於for迴圈的物件都是Iterable型別;
凡是可作用於next()函式的物件都是Iterator型別,它們表示一個惰性計算的序列;
集合資料型別如list、dict、str等是Iterable但不是Iterator,不過可以通過iter()函式獲得一個Iterator物件。
Python的for迴圈本質上就是通過不斷呼叫next()函式實現的,例如:

for x in [1, 2, 3, 4, 5]:
    pass
#完全等價於:
# 首先獲得Iterator物件:
it = iter([1, 2, 3, 4, 5])
# 迴圈:
while True:
    try:
        # 獲得下一個值:
        x = next(it)
    except StopIteration:
        # 遇到StopIteration就退出迴圈
        break    

 

 

tuple: 

tuple是特殊的list,用()來定義,他一旦定義就不能變更

>>> classmates = ('Michael', 'Bob', 'Tracy')

只有一個元素的tuple必須用,分開以免歧義,否則會被認為是一個元素本身,而非只含一個元素的tuple,

>>> t = (1,)
>>> t
(1,)

python切片slice

https://stackoverflow.com/questions/509211/understanding-pythons-slice-notation

a[start:end] # items start through end-1
a[start:]    # items start through the rest of the array
a[:end]      # items from the beginning through end-1
a[:]         # a copy of the whole array
a[start:end:step] # start through not past end, by step
a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items
a[::-1]    # all items in the array, reversed
a[1::-1]   # the first two items, reversed
a[:-3:-1]  # the last two items, reversed
a[-3::-1]  # everything except the last two items, reversed

numpy ndarray indexing/slice

https://docs.scipy.org/doc/numpy/reference/arrays.indexing.html

ndarray可以使用標準的python $x[obj]$方式來訪問和切片,這裡$x$是陣列本身,而$obj$是相應的選擇表示式。ndarray支援3中不同的index方式:field access, basic slicing, advanced indexing,具體使用哪一種取決於$obj$本身。

注意:

$x[(exp1, exp2, ..., expN)] 等價於 x[exp1, exp2, ..., expN]$

basic slicing and indexing

ndarray的basic slicing將python僅能針對一維陣列的基礎index和slicing概念擴充到N維。當前面的$x[obj]$ slice形式中的obj為一個slice物件($[start:stop:step]$格式),或者一個整數,或者$(slice obj,int)$時,這就是basic slicing。basic slicing的標準規則在每個緯度上分別應用。

所有basic slicing產生的陣列實際上是原始陣列的view,資料本身並不會複製。

以下是抽象出來的基礎順序切片規則

$i:j:k$,$i = start:end:step$,其中,如果$i,j$為負數,則可以理解為$n+i,n+j$,n是相應維度上元素的個數。如果$k<0$,則表示走向到更小的indices.

>>> x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> x[1:7:2]
array([1, 3, 5])
>>> x[-2:10]
array([8, 9])
>>> x[-3:3:-1]
array([7, 6, 5, 4])
>>> x[5:]
array([5, 6, 7, 8, 9])
>>> x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
>>> x.shape
(2, 3, 1)
>>> x[1:2]
array([[[4],
        [5],
        [6]]])
>>> x[...,0]
array([[1, 2, 3],
       [4, 5, 6]])
>>> x[:,np.newaxis,:,:].shape
(2, 1, 3, 1)

advanced indexing

如果selction obj不是一個sequence obj的tuple,而是一個值為int或者bool的ndarray,或者是至少包含一個start:end:step或int/bool性ndarray的tuple,則就會應用advanced indexing.有兩種模式:integer和boolean

高階index總會返回資料的一份copy(基礎slicing只返回一個view,而未做copy!)

注意:

  • $x[(1,2,3),]$: 高階slicing
  • $x[(1,2,3)] = x[1,2,3]$: basic slicing

advanced integer array indexing

>>> x = array([[ 0,  1,  2],
...            [ 3,  4,  5],
...            [ 6,  7,  8],
...            [ 9, 10, 11]])
>>> rows = np.array([[0, 0],
...                  [3, 3]], dtype=np.intp)
>>> columns = np.array([[0, 2],
...                     [0, 2]], dtype=np.intp)
>>> x[rows, columns]
array([[ 0,  2],
       [ 9, 11]])
>>> x = np.array([[1, 2], [3, 4], [5, 6]])
>>> x[[0, 1, 2], [0, 1, 0]]
array([1, 4, 5])

Boolean array indexing

如果obj是一個boolean值的陣列,則使用該slicing策略。

>>> x = np.array([[1., 2.], [np.nan, 3.], [np.nan, np.nan]])
>>> x[~np.isnan(x)]
array([ 1.,  2.,  3.])
>>> x = np.array([1., -1., -2., 3])
>>> x[x < 0] += 20
>>> x
array([  1.,  19.,  18.,   3.])
>>> x = np.array([[0, 1], [1, 1], [2, 2]])
>>> rowsum = x.sum(-1)
>>> x[rowsum <= 2, :]
array([[0, 1],
       [1, 1]])
>>> rowsum = x.sum(-1, keepdims=True)
>>> rowsum.shape
(3, 1)
>>> x[rowsum <= 2, :]    # fails
IndexError: too many indices
>>> x[rowsum <= 2]
array([0, 1])
>>> x = array([[ 0,  1,  2],
...            [ 3,  4,  5],
...            [ 6,  7,  8],
...            [ 9, 10, 11]])
>>> rows = (x.sum(-1) % 2) == 0
>>> rows
array([False,  True, False,  True])
>>> columns = [0, 2]
>>> x[np.ix_(rows, columns)]
array([[ 3,  5],
       [ 9, 11]])
>>> rows = rows.nonzero()[0]
>>> x[rows[:, np.newaxis], columns]
array([[ 3,  5],
       [ 9, 11]])

pandas indexing and slicing

https://pandas.pydata.org/pandas-docs/stable/indexing.html 

假設我們有以下資料集,我們來練習使用pandas做資料檢索和切片:

# Import cars data
import pandas as pd
cars = pd.read_csv('cars.csv', index_col = 0)
# Print out country column as Pandas Series
print(cars['country'])
In [4]: cars['country']
Out[4]: 
US     United States
AUS        Australia
JAP            Japan
IN             India
RU            Russia
MOR          Morocco
EG             Egypt
Name: country, dtype: object: Pandas Series
# Print out country column as Pandas DataFrame
print(cars[['country']])
In [5]: cars[['country']]
Out[5]: 
           country
US   United States
AUS      Australia
JAP          Japan
IN           India
RU          Russia
MOR        Morocco
EG           Egypt
# Print out DataFrame with country and drives_right columns
print(cars[['country','drives_right']])
In [6]: cars[['country','drives_right']]
Out[6]: 
           country  drives_right
US   United States          True
AUS      Australia         False
JAP          Japan         False
IN           India         False
RU          Russia          True
MOR        Morocco          True
EG           Egypt          True
# Print out first 3 observations
print(cars[0:4])

# Print out fourth, fifth and sixth observation
print(cars[4:7])

# Print out first 3 observations
print(cars[0:4])

# Print out fourth, fifth and sixth observation
print(cars[4:7])
In [14]: cars
Out[14]: 
     cars_per_cap        country  drives_right
US            809  United States          True
AUS           731      Australia         False
JAP           588          Japan         False
IN             18          India         False
RU            200         Russia          True
MOR            70        Morocco          True
EG             45          Egypt          True

In [15]: cars.loc['RU']
Out[15]: 
cars_per_cap       200
country         Russia
drives_right      True
Name: RU, dtype: object

In [16]: cars.iloc[4]
Out[16]: 
cars_per_cap       200
country         Russia
drives_right      True
Name: RU, dtype: object

In [17]: cars.loc[['RU']]
Out[17]: 
    cars_per_cap country  drives_right
RU           200  Russia          True

In [18]: cars.iloc[[4]]
Out[18]: 
    cars_per_cap country  drives_right
RU           200  Russia          True

In [19]: cars.loc[['RU','AUS']]
Out[19]: 
     cars_per_cap    country  drives_right
RU            200     Russia          True
AUS           731  Australia         False

In [20]: cars.iloc[[4,1]]
Out[20]: 
     cars_per_cap    country  drives_right
RU            200     Russia          True
AUS           731  Australia         False
In [3]: cars.loc['IN','cars_per_cap']
Out[3]: 18

In [4]: cars.iloc[3,0]
Out[4]: 18

In [5]: cars.loc[['IN','RU'],'cars_per_cap']
Out[5]: 
IN     18
RU    200
Name: cars_per_cap, dtype: int64

In [6]: cars.iloc[[3,4],0]
Out[6]: 
IN     18
RU    200
Name: cars_per_cap, dtype: int64

In [7]: cars.loc[['IN','RU'],['cars_per_cap','country']]
Out[7]: 
    cars_per_cap country
IN            18   India
RU           200  Russia

In [8]: cars.iloc[[3,4],[0,1]]
Out[8]: 
    cars_per_cap country
IN            18   India
RU           200  Russia
print(cars.loc['MOR','drives_right'])
True
In [1]: cars.loc[:,'country']
Out[1]: 
US     United States
AUS        Australia
JAP            Japan
IN             India
RU            Russia
MOR          Morocco
EG             Egypt
Name: country, dtype: object

In [2]: cars.iloc[:,1]
Out[2]: 
US     United States
AUS        Australia
JAP            Japan
IN             India
RU            Russia
MOR          Morocco
EG             Egypt
Name: country, dtype: object

In [3]: cars.loc[:,['country','drives_right']]
Out[3]: 
           country  drives_right
US   United States          True
AUS      Australia         False
JAP          Japan         False
IN           India         False
RU          Russia          True
MOR        Morocco          True
EG           Egypt          True

In [4]: cars.iloc[:,[1,2]]
Out[4]: 
           country  drives_right
US   United States          True
AUS      Australia         False
JAP          Japan         False
IN           India         False
RU          Russia          True
MOR        Morocco          True
EG           Egypt          True

 

if判斷:

age = 3
if age >= 18:
  print('adult')
elif age >= 6:
  print('teenager')
else:
  print('kid')

迴圈:

names = ['Michael', 'Bob', 'Tracy']
for name in names:
  print(name)
>>> list(range(5))
[0, 1, 2, 3, 4]
sum =0
for x in range(101):
    sum = sum+x
print(sum)

dist字典

dist資料類似於javascript的object,由key-value來定義的物件

>>> d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
>>> d['Michael']
95

set(集合)

set和dist類似,但是它只儲存key,不存value,就像是js中literal物件{1,2,3,'a','b'},可以看成數學意義上的無序和無重複元素的集和,支援交集,並集等集合操作,由一個list輸入傳給set()函式來生成

>>> s = set([1, 2, 3])
>>> s
{1, 2, 3}
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s1 & s2
{2, 3}
>>> s1 | s2
{1, 2, 3, 4}

str,int,None是不可變物件,而List,dict是可變物件

幫助資源查詢:

https://docs.python.org/3/library/functions.html#abs

函式:

函式有def來定義,可以返回多個值

import math
def move(x, y, step, angle=0):
    nx = x + step * math.cos(angle)
    ny = y - step * math.sin(angle)
    return nx, ny
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print(x, y)
151.96152422706632 70.0
>>> r = move(100, 100, 60, math.pi / 6)
>>> print(r)
#本質上函式返回的是一個tuple,而這個tuple的對應元素的值分別賦值給了左變數
(151.96152422706632, 70.0)

函式支援預設引數:

def enroll(name, gender, age=6, city='Beijing'):
    print('name:', name)
    print('gender:', gender)
    print('age:', age)
    print('city:', city)
enroll('Bob', 'M', 7)
enroll('Adam', 'M', city='Tianjin')

函式可變引數:

def calc(*numbers):
    sum = 0
   print(type(numbers))
# 注意這裡的numbers是tuple資料<class 'tuple'>
for n in numbers:
sum
= sum + n * n return sum >>> nums = [1, 2, 3] >>> calc(*nums) #加一個*把list或者tuple變成可變引數傳進去*nums表示把nums這個list的所有元素作為可變引數傳進去 14

函式關鍵字引數:

def person(name, age, **kw):
    print('name:', name, 'age:', age, 'other:', kw)
   print(type(kw)) # 注意kw是dict資料型別: <class 'dict'>
>>> person('Michael', 30) name: Michael age: 30 other: {} >>> person('Bob', 35, city='Beijing') name: Bob age: 35 other: {'city': 'Beijing'} >>> person('Adam', 45, gender='M', job='Engineer') name: Adam age: 45 other: {'gender': 'M', 'job': 'Engineer'}

>>> extra = {'city': 'Beijing', 'job': 'Engineer'}
>>> person('Jack', 24, **extra)
name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}

**extra表示把extra這個dict的所有key-value用關鍵字引數傳入到函式的**kw引數,kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函式外的extra

命名關鍵字引數:

def person(name, age, *, city='Beijing', job):  #含預設值的命名關鍵字引數,city預設就為'beijing'
    print(name, age, city, job)
>>> person('Jack', 24, city='Beijing', job='Engineer')
Jack 24 Beijing Engineer

 

關鍵字引數有什麼用?它可以擴充套件函式的功能。比如,在person函式裡,我們保證能接收到name和age這兩個引數,但是,如果呼叫者願意提供更多的引數,我們也能收到。試想你正在做一個使用者註冊的功能,除了使用者名稱和年齡是必填項外,其他都是可選項,利用關鍵字引數來定義這個函式就能滿足註冊的需求

map

很多高階語言都提供類似的功能,其作用是對於list裡面的每一個元素都執行相同的函式,並且返回一個iterator,進而可以使用list()函式來生成新的list

def f(x):
    return x*x
r = map(f,[1,2,3,4,5])
print(r)
print(isinstance(r, Iterator)) # True
print(list(r)) #結果如下 #<map object at 0x000000000072B9B0>, 返回結果是一個Iterator,因此必須通過list()呼叫才能生成list #[1, 4, 9, 16, 25]

Modules:

https://pypi.python.org/pypi/mysql-connector-python/2.0.4

 

image module code example:

from PIL import  Image
im = Image.open(r'C:\Users\Administrator\Desktop\jj.png')
print(im.format,im.size,im.mode)
im.thumbnail((100,50))
im.save('thumb.jpg','png')

Python網路服務程式設計

服務端:

import  socket
import threading
import time
def tcplink(sock,addr):
    print(('Accept new connection from %s:%s...' % addr))
    sock.send(b'Welcome, client!')
    while True:
        data = sock.recv(1024)
        time.sleep(1)
        if not data or data.decode('utf-8') == 'exit':
            break
        sock.send(('Hello, %s!' % data).encode('utf-8'))
    sock.close()
    print('Connection from %s:%s closed.' %addr)
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.bind(('127.0.0.1',9999))
s.listen(5)
print('waiting for connection coming on server...')
while True:
    sock, addr = s.accept()
    t = threading.Thread(target=tcplink,args=(sock,addr))
    t.start()
#下面是server端的列印資訊:

waiting for connection coming on server...
Accept new connection from 127.0.0.1:64891...
Connection from 127.0.0.1:64891 closed.
Accept new connection from 127.0.0.1:65304...
Connection from 127.0.0.1:65304 closed.
Accept new connection from 127.0.0.1:65408...
Connection from 127.0.0.1:65408 closed.
Accept new connection from 127.0.0.1:65435...
Connection from 127.0.0.1:65435 closed.
Accept new connection from 127.0.0.1:65505...
Connection from 127.0.0.1:65505 closed.

 

 

測試客戶端

import  socket
import threading
import time
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('127.0.0.1',9999))
print((s.recv(1024).decode('utf-8')))
for data in [b'Michael',b'Tracy',b'Sarah']:
    s.send(data)
    print(s.recv(1024).decode('utf-8'))
s.send(b'exit')
s.close()
#下面是客戶端的列印資訊:

Welcome, client!
Hello, b'Michael'!
Hello, b'Tracy'!
Hello, b'Sarah'!

 

python vs. iPython. vs jupyter notebooks以及演進路線架構

ipython notebook->jupyter notebooks演進

總的來說分為interface level和kernel level兩個領域,介面這一層可以有notebooks,ipython console, qt console,直接通過一個MQ over socket和kernel level通訊,該通訊介面負責傳輸要執行的python code以及code執行完成後返回的data

而jupyter將notebooks的這種模式擴充套件到多種語言,比如R, bash,在kernel層分別增加對應語言的kernel元件,負責對應語言的執行和返回結果。

https://plot.ly/python/ipython-vs-python/

jupyter notebooks的工作原理架構

到底什麼是IPython?

IPython是一個增強互動能力的python console環境,它提供了很多有用的feature:

和標準的python console相比,它提供: Tab completion的功能,exlporing your objects,比如通過object_name?就將列出所有關於物件的細節。Magic functions, 比如%timeit這個magic常常可以用來檢查程式碼執行的效率, %run這個magic可以允許你執行任何python scirpt並且將其所有的data直接載入到互動環境中。執行系統shell commands,比如!ping www.xxx.com, 也可以獲取到系統指令碼命令輸出的內容:

files = !ls 

!grep -rF $pattern ipython/*.

將python的變數$pattern傳入上面的grep系統命令

http://ipython.org/ipython-doc/dev/interactive/tutorial.html#magic-functions

如何在ipython下直接執行 <<<的例子程式碼?

答案是在ipython下執行以下命令

%doctest_mode

如何使用notebooks學習和開發python?

Jupyter notebook軟體在至少以下兩種場景中非常好用:

1. 希望針對已經存在的notebook做進一步實驗或者純粹的學習;

2. 希望自己開發一個notebook用於輔助教學或者生成學術文章

在這兩種場景下,你可能都希望在一個特定的目錄下執行Jupyter notebook:

cd到你的目錄中,執行以下命令:

jupyter notebook

即可開啟notebook,並且列出該目錄下的所有檔案: http://localhost:8888/tree

some python debug study tips:

1. dir(obj) 列出物件的所有屬性和方法

y=[x*x for x in range(1,11)]
print(dir(y))
# 輸出:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']

2. 在notebook ipython環境中,使用%who magic 命令列出名稱空間中所有global變數

%who Series
#列出所有Series型別的變數
s     temp_diffs     temps1     temps2     
%who
#列出所有global
DataFrame     Series     dates     np     pd     plt     s     temp_diffs     temps1     
temps2     
%whos
#列出所有global及其詳細的type:
Variable     Type             Data/Info
---------------------------------------
DataFrame    type             <class 'pandas.core.frame.DataFrame'>
Series       type             <class 'pandas.core.series.Series'>
dates        DatetimeIndex    DatetimeIndex(['2014-07-0<...>atetime64[ns]', freq='D')
my_func      function         <function my_func at 0x00000211211B7C80>
np           module           <module 'numpy' from 'C:\<...>ges\\numpy\\__init__.py'>
pd           module           <module 'pandas' from 'C:<...>es\\pandas\\__init__.py'>
plt          module           <module 'matplotlib.pyplo<...>\\matplotlib\\pyplot.py'>
s            Series           a    1\nb    2\nc    3\nd    4\ndtype: int64
temp_diffs   Series           2014-07-01    10\n2014-07<...>10\nFreq: D, dtype: int64
temps1       Series           2014-07-01    80\n2014-07<...>87\nFreq: D, dtype: int64
temps2       Series           2014-07-01    70\n2014-07<...>77\nFreq: D, dtype: int64

 3. 檢視一個module定義的方法以及方法的詳細用法

import pandas as pd
print(dir(pd))
print(help(pd.Series))
['Categorical', 'CategoricalIndex', 'DataFrame', 'DateOffset', 'DatetimeIndex', 'ExcelFile', 'ExcelWriter', 'Expr', 'Float64Index', 'Grouper', 'HDFStore', 'Index', 'IndexSlice', 'Int64Index', 'MultiIndex', 'NaT', 'Panel', 'Panel4D', 'Period', 'PeriodIndex', 'RangeIndex', 'Series', 'SparseArray', 'SparseDataFrame', 'SparseList', 'SparsePanel', 'SparseSeries', 'SparseTimeSeries', 'Term', 'TimeGrouper', 'TimeSeries', 'Timedelta', 'TimedeltaIndex', 'Timestamp', 'WidePanel', '__builtins__', '__cached__', '__doc__', '__docformat__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', '__version__', '_np_version_under1p10', '_np_version_under1p11', '_np_version_under1p12', '_np_version_under1p8', '_np_version_under1p9', '_period', '_sparse', '_testing', '_version', 'algos', 'bdate_range', 'compat', 'computation', 'concat', 'core', 'crosstab', 'cut', 'date_range', 'datetime', 'datetools', 'dependency', 'describe_option', 'eval', 'ewma', 'ewmcorr', 'ewmcov', 'ewmstd', 'ewmvar', 'ewmvol', 'expanding_apply', 'expanding_corr', 'expanding_count', 'expanding_cov', 'expanding_kurt', 'expanding_max', 'expanding_mean', 'expanding_median', 'expanding_min', 'expanding_quantile', 'expanding_skew', 'expanding_std', 'expanding_sum', 'expanding_var', 'factorize', 'fama_macbeth', 'formats', 'get_dummies', 'get_option', 'get_store', 'groupby', 'hard_dependencies', 'hashtable', 'index', 'indexes', 'infer_freq', 'info', 'io', 'isnull', 'json', 'lib', 'lreshape', 'match', 'melt', 'merge', 'missing_dependencies', 'msgpack', 'notnull', 'np', 'offsets', 'ols', 'option_context', 'options', 'ordered_merge', 'pandas', 'parser', 'period_range', 'pivot', 'pivot_table', 'plot_params', 'pnow', 'qcut', 'read_clipboard', 'read_csv', 'read_excel', 'read_fwf', 'read_gbq', 'read_hdf', 'read_html', 'read_json', 'read_msgpack', 'read_pickle', 'read_sas', 'read_sql', 'read_sql_query', 'read_sql_table', 'read_stata', 'read_table', 'reset_option', 'rolling_apply', 'rolling_corr', 'rolling_count', 'rolling_cov', 'rolling_kurt', 'rolling_max', 'rolling_mean', 'rolling_median', 'rolling_min', 'rolling_quantile', 'rolling_skew', 'rolling_std', 'rolling_sum', 'rolling_var', 'rolling_window', 'scatter_matrix', 'set_eng_float_format', 'set_option', 'show_versions', 'sparse', 'stats', 'test', 'timedelta_range', 'to_datetime', 'to_msgpack', 'to_numeric', 'to_pickle', 'to_timedelta', 'tools', 'tseries', 'tslib', 'types', 'unique', 'util', 'value_counts', 'wide_to_long']

Help on class Series in module pandas.core.series:

class Series(pandas.core.base.IndexOpsMixin, pandas.core.strings.StringAccessorMixin, pandas.core.generic.NDFrame)
 |  One-dimensional ndarray with axis labels (including time series).
 |  
 |  Labels need not be unique but must be any hashable type. The object

 4. notebooks中的命令模式和編輯模式相關命令:

Numpy

為何要引入Numpy?

由於標準的python list中儲存的是物件的指標,因此必須二次定址才能訪問到list中的元素。顯然這是低效並且浪費空間的。。

並且標準python list或者array不支援二緯陣列,也不支援對陣列資料做一些複雜適合數字運算的函式。

numpy為了提高效能,並且支援二緯陣列的複雜運算使用C語言編寫底層的實現並且以python obj方式給python呼叫。

其核心實現了以下兩個東西:

  • ndarray :它是儲存單一資料型別的多緯陣列,並且基於該陣列能夠支援多種複雜的運算函式
  • ufunc:如果numpy提供的標準運算函式不滿足需求,你可以使用這種機制定義自己的函式
  • 應用在ndarray陣列中的數字上做數值運算時,都將是element wise的,也就是逐元素計算的!
import numpy as np
from matplotlib import pyplot as plt
x = np.linspace(0,2 * np.pi,100)
y = np.sin(x) // y是對x中的所有元素執行sin計算
plt.plot(x,y,'r-',linewidth=3,label='sin function')
plt.xlabel('x')
plt.ylabel('sin(x)')
plt.show()

上面的程式碼先產生0到$2\pi$的等差陣列,然後傳遞給np.sin()函式,逐個計算其sin值。由於np.sin()是一個ufunc函式,因此其內部對陣列x的每個元素進行迴圈,分別計算他們的正弦值,將結果儲存為一個陣列並返回

numpy高階特性(broadcasting, ufunc詳解)

https://www.jianshu.com/p/3c3f7da88516

參看<<利用Python進行資料分析·第2版>>

Pandas

為何需要pandas

numpy的2d陣列雖然可以模擬pandas提供的功能,但是主要numpy原生的2d陣列必須使用相同的資料型別,而在現實的資料分析任務中很多是不同型別的。

pandas在numpy之上又提供了類似於sql資料處理機制,提供Series和Dataframe兩種資料型別。 每個Series實際上包含index和values兩個ndarray.其中index儲存建立series時傳入的index資訊,values則是儲存對應值的ndarray陣列。numpy的ufunc函式都對該values陣列來執行.

 

 

pandas dataframe圖解

http://www.tetraph.com/blog/machine-learning/jupyter-notebook-keyboard-shortcut-command-mode-edit-mode/

dataframe.loc/iloc vs []index operator

.oc/iloc都是指的row,而[]則預設給column selection, column總歸會有一個name,因此column selection總是label based

df.loc[:,['Name','cost']]
#返回所有store的name和cost value

如何複製而不是引用相同的list?

shoplist = ['apple','mango','carrot','banana']
mylist = shoplist
del shoplist[0]
print('shoplist is:',shoplist)
print('mylist is:',mylist)
# 上面是相同的輸出
print('copy via slice and asignment')
mycopiedlist = shoplist[:] # make a copy by doing a full slice
del(mycopiedlist[0])
print('shoplist is: ',shoplist)
print('mycopiedlist is:',mycopiedlist)

從字串直接建立單字母的list

list('ABCD')
# 輸出 ['A', 'B', 'C', 'D']

python list .vs. numpy .vs. pandas

如何在ipython shell中檢視已經load進namespace的函式原始碼?

有的時候,我們通過ipython shell做探索式程式設計,有一些函式已經做了定義和執行,隨後想再檢視一下這個函式的程式碼,並且準備呼叫它,這時你就需要想辦法“重現”該函式的程式碼。

方法是:通過inspect模組

import inspect
source_DF = inspect.getsource(pandas.DataFrame)
print(type(source_DF))
print(source_DF[:200]) #列印源程式程式碼
source_file_DF = inspect.getsourcefile(pandas.DataFrame)
print(source_file_DF)
# D:\Users\dengdong\AppData\Local\Continuum\anaconda3\lib\site-packages\pandas\core\frame.py

如何得到python變數的地址address?

a = [0,1,2,3,4,5,6,7,8,9]
b = a[:]
print(id(a))
# 54749320
print(id(b))
# 54749340

 

相關文章