1. 程式人生 > >一句python,一句R︱列表、元組、字典、資料型別、自定義模組匯入(格式、去重)

一句python,一句R︱列表、元組、字典、資料型別、自定義模組匯入(格式、去重)

先學了R,最近剛剛上手python,所以想著將python和R結合起來互相對比來更好理解python。最好就是一句python,對應寫一句R。

pandas中有類似R中的read.table的功能,而且很像。

————————————————————————————————————————————————————

一、資料型別

Python有五個標準的資料型別:

  • Numbers(數字)
  • String(字串)
  • List(列表)              使用:[]      list()
  • Tuple(元組)          使用:()  tuple()
  • Dictionary(字典)   使用:{ }    dict()
其中pandas和numpy中的陣列格式 以及Series DataFrame都是基於此之上而得到的。其中比R要多:Tuple、Dictionary兩種型別。

1、數字格式 int()  float() long()  complex()

Python支援四種不同的數字型別:

  • int(有符號整型)
  • long(長整型[也可以代表八進位制和十六進位制])
  • float(浮點型)
  • complex(複數)

一些數值型別的例項:

intlongfloatcomplex
1051924361L0.03.14j
100-0x19323L15.2045.j
-7860122L-21.99.322e-36j
0800xDEFABCECBDAECBFBAEl32.3+e18.876j
-0490535633629843L-90.-.6545+0J
-0x260-052318172735L-32.54e1003e+26J
0x69-4721885298529L70.2-E124.53e-7j
  • 長整型也可以使用小寫"L",但是還是建議您使用大寫"L",避免與數字"1"混淆。Python使用"L"來顯示長整型。
  • Python還支援複數,複數由實數部分和虛數部分構成,可以用a + bj,或者complex(a,b)表示, 複數的實部a和虛部b都是浮點型

格式轉換

格式判斷:

import types
if type(1) is types.Integer:
    print('1是int型別')
else:
    print('1不是int型別')
還可使用:
isinstance(2, float)


以下幾個內建的函式可以執行資料型別之間的轉換。這些函式返回一個新的物件,表示轉換的值。

函式描述

int(x [,base])

將x轉換為一個整數

long(x [,base] )

將x轉換為一個長整數

float(x)

將x轉換到一個浮點數

complex(real [,imag])

建立一個複數

str(x)

將物件 x 轉換為字串

repr(x)

將物件 x 轉換為表示式字串

eval(str)

用來計算在字串中的有效Python表示式,並返回一個物件

tuple(s)

將序列 s 轉換為一個元組

list(s)

將序列 s 轉換為一個列表

set(s)

轉換為可變集合

dict(d)

建立一個字典。d 必須是一個序列 (key,value)元組。

frozenset(s)

轉換為不可變集合

chr(x)

將一個整數轉換為一個字元

unichr(x)

將一個整數轉換為Unicode字元

ord(x)

將一個字元轉換為它的整數值

hex(x)

將一個整數轉換為一個十六進位制字串

oct(x)

將一個整數轉換為一個八進位制字串



2、字串 str()

字串或串(String)是由數字、字母、下劃線組成的一串字元。

可參考:

其中:

字串中的反引號為:

>>> print b + repr(a)   #repr(a)與上面的類似
free1989 

這裡 repr()是一個函式,其實就是反引號的替代品,它能夠把結果字串轉化為合法的 python 表示式。

可能看官看到這個,就要問它們三者之間的區別了。首先明確,repr()和 \ 是一致的,就不用區別了。接下來需要區別的就是 repr()和 str,一個最簡單的區別,repr 是函式,str 是跟 int 一樣,一種物件型別。

————————————————————————————————————————————————————

二、列表型/list/ []  =R=c()向量

速查手冊:

L.append(var)   #追加元素  
L.insert(index,var)  
L.pop(var)      #返回最後一個元素,並從list中刪除之  
L.remove(var)   #刪除第一次出現的該元素  
L.count(var)    #該元素在列表中出現的個數  
L.index(var)    #該元素的位置,無則拋異常   
L.extend(list)  #追加list,即合併list到L上  
L.sort()        #排序  
L.reverse()     #倒序  
list 操作符:,+,*,關鍵字del  
a[1:]       #片段操作符,用於子list的提取  
[1,2]+[3,4] #為[1,2,3,4]。同extend()  
[2]*4       #為[2,2,2,2]  
del L[1]    #刪除指定下標的元素  
del L[1:3]  #刪除指定下標範圍的元素  
list的複製  
L1 = L      #L1為L的別名,用C來說就是指標地址相同,對L1操作即對L操作。函式引數就是這樣傳遞的  
L1 = L[:]   #L1為L的克隆,即另一個拷貝。  

List(列表) 是 Python 中使用最頻繁的資料型別。

列表可以完成大多數集合類的資料結構實現。它支援字元,數字,字串甚至可以包含列表(所謂巢狀)。

list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tinylist = [123, 'john']

list中的元素追加,那可以直接:

list = []

list = list + list

或者list.append

append是新增單個元素,如果要追加同樣元組,可以用list.extend

[]或者() 追加用 加號 + 或者 list.append

兩個列表同時迭代:

nfc = ["Packers", "49ers"]
afc = ["Ravens", "Patriots"]
for teama, teamb in zip(nfc, afc):
     print teama + " vs. " + teamb
>>> Packers vs. Ravens
>>> 49ers vs. Patriots
 

格式轉化:

(1)列表轉為字串

''.join(a)

(2)列表轉換為元組

l = ['a','b','c']

tuple(l)

(3)列表轉換為字典

list1 = dic.items()

dict(list1)

(4)把List壓平

sum(list,[])

[[1,2,3], [5, 2, 8], [7,8,9]]
[1,2,3,5,2,8,7,8,9]
其餘方式可參考:https://www.zhihu.com/question/27010691

————————————————————————————————————————————————————

三、元組——()/ tuple()  =R= 固定的c()

元組是另一個數據型別,類似於List(列表)。

元組用"()"標識。內部元素用逗號隔開。但是元組不能二次賦值,相當於只讀列表。不能用append來新賦值

以下是元組無效的,因為元組是不允許更新的。而列表是允許更新的:
#!/usr/bin/python
# -*- coding: UTF-8 -*-

tuple = ( 'abcd', 786 , 2.23, 'john', 70.2 )
list = [ 'abcd', 786 , 2.23, 'john', 70.2 ]
tuple[2] = 1000 # 元組中是非法應用
list[2] = 1000 # 列表中是合法應用

相當於固定的c()

元組中元素的追加,就可以直接用:

用 '+' 號

a+a

元組不可以用append新增元素

格式轉化:

元組轉換為字串

''.join(t)

元組轉換為列表

t = ('a','b','c')

list(t)

['a','b','c']


————————————————————————————————————————————————————

四、Python元字典 { }  =R= list()

字典(dictionary)是除列表以外python之中最靈活的內建資料結構型別。列表是有序的物件結合,字典是無序的物件集合。

兩者之間的區別在於:字典當中的元素是通過鍵來存取的,而不是通過偏移存取。

字典用"{ }"標識。字典由索引(key)和它對應的值value組成。

速查手冊:

dictionary的方法  
D.get(key, 0)       #同dict[key],多了個沒有則返回預設值,0。[]沒有則拋異常  
D.has_key(key)      #有該鍵返回TRUE,否則FALSE  
D.keys()            #返回字典鍵的列表  
D.values()          #以列表的形式返回字典中的值,返回值的列表中可包含重複元素  
D.items()           #將所有的字典項以列表方式返回,這些列表中的每一項都來自於(鍵,值),但是項在返回時並沒有特殊的順序           
  
D.update(dict2)     #增加合併字典  
D.popitem()         #得到一個pair,並從字典中刪除它。已空則拋異常  
D.clear()           #清空字典,同del dict  
D.copy()            #拷貝字典  
D.cmp(dict1,dict2)  #比較字典,(優先順序為元素個數、鍵大小、鍵值大小)  
                    #第一個大返回1,小返回-1,一樣返回0  
              
dictionary的複製  
dict1 = dict        #別名  
dict2=dict.copy()   #克隆,即另一個拷貝。  


生成方式一:用在函式、for迴圈中

dict = {}

dict['one'] = "This is one"
dict[2] = "This is two"

但是dict有一個好處,就是不僅可以list[1] 還可以list[strings],其中可以裝下字元。

生成方式二:{}

tinydict = {'name': 'john','code':6734, 'dept': 'sales'}

輸出方式:

print dict[2] # 輸出鍵為 2 的值
print tinydict # 輸出完整的字典
print tinydict.keys() # 輸出所有鍵
print tinydict.values() # 輸出所有值

延伸

一種特殊的,字典的生成方式:

dict(dim=[1, 3, 227, 227])

格式轉化,由list->陣列:

np.array('d',[1,2,3])

轉回來的話呼叫tolist函式

_.tolist()
還有一種方式是:.toarray()變為array

延伸二:dict格式轉化

字典轉換為列表
dic={'a':1,'b':2}
dic.items()
[('a',1),('b',2)]
或者:
D.get(key, 0)       #同dict[key],多了個沒有則返回預設值,0。[]沒有則拋異常  
D.has_key(key)      #有該鍵返回TRUE,否則FALSE  
D.keys()            #返回字典鍵的列表  
D.values()          #以列表的形式返回字典中的值,返回值的列表中可包含重複元素  
D.items()           #將所有的字典項以列表方式返回,這些列表中的每一項都來自於(鍵,值),但是項在返回時並沒有特殊的順序           

其中的.values()就可以實現dict轉化為list

字串轉化為字典:

eval(user)

字典轉dataframe:

def dict2dataframe(content_dict):
    return pd.DataFrame(list(content_dict.values()), index = list(content_dict.keys()))


延伸三:去掉List中的空格

filter(None,[None,1,2,3,None])

即可

延伸四:兩個dict合併

dict(dict1, **dict2)




————————————————————————————————————————————————————

五、模組、模組匯入與複查、自定義模組

1、一般傳統模組

下載模組是一個麻煩的事情,一般用pip來執行,但是貌似每次下載都是一堆麻煩提示,於是轉而用pycharm,很方面,傻瓜版.

一般模組就像R中的函式包,需要先呼叫

library(packages)=import pandas as pd

檢視模組是否載入,一般import pandas,如果該包下載就不會用任何提示,如果沒有載入成功,就會報錯:
ImportError: No module named da

檢視已有的載入包

help("modules")    #檢視安裝包

按照R語言中曾經存在的問題:

1、如何取消模組的載入?

2、模組的位置是在哪?

3、模組的資訊如何調用出來?就像R中的介紹一樣,有沒有比較詳細的說明?

2、自定義模組匯入

上網查了下資料和自己實驗了下,有幾個方法:

1.如果匯入的模組和主程式在同個目錄下,直接import就行了

2.如果匯入的模組是在主程式所在目錄的子目錄下,可以在子目錄中增加一個空白的__init__.py檔案,該檔案使得python直譯器將子目錄整個也當成一個模組,然後直接通過“import 子目錄.模組”匯入即可。

3.如果匯入的模組是在主程式所在目錄的父目錄下,則要通過修改path來解決,有兩種方法:

(1)通過”import sys,sys.path.append('父目錄的路徑')“來改變,這種方法屬於一次性的,只對當前的python直譯器程序有效,關掉python重啟後就失效了。

(2)直接修改環境變數:在windows中是 “ set 變數=‘路徑’  ” 例如:set PYTHONPATH=‘C:\test\...’ 檢視是否設定成功用echo %PYTHONPATH%,而且進到python直譯器中檢視sys.path,會發現已經有了新增加的路徑了。這 種方式是永久的,一次設定以後一直都有效。在linux中是 "export 變數=‘路徑’ “,檢視是" echo $變數 "

通過修改path是通用的方法,因為python直譯器就是通過sys.path去一個地方一個地方的尋找模組的。

筆者實踐一般用第二種辦法,__init__.py檔案,同時譬如現在有這樣的目錄結構:

C:\\Users\\filename\\function_file\\file.function.py

file.function.py裡面裝著function1函式。

import sys
ImportPath = 'C:\\Users\\filename'
sys.path.append(ImportPath)
from function_file.function import function1

如果報錯:

python ImportError: cannot import name

一般是.pyc檔案的問題,找到對應的pyc刪除掉

————————————————————————————————————————

六、資料讀入、寫出

1、python的read_csv

#資料匯入
df = pd.read_csv('./cpu.csv',header=0)
#中文encoding = 'gbk'

約等於R中的read.csv('./cpu.csv',header=T,encoding= UTF-8)

pd.read_csv("C:\\Users\\long\\Desktop\\ex2.csv",header=None,names=["a","b","c","e","message"],index_col=["message","a"])
其中:header=None,就代表沒有行名稱,names代表另外命名行名稱,index_col代表列。

其中讀入資料的時候,不要出現中文,不然讀不進去。

會出現以下的錯誤:

IOError: File C:\Users\long\Desktop\ch06\ex2.csv does not exist

如果出現中文,中文匯入、匯出都需要加上:

df = pd.read_csv("001.csv",encoding="gbk")
dataname.to_csv("001.csv",encoding="gbk")


2、python的to_csv

to_csv=write.csv

#資料匯出
df.to_csv('uk_rain.csv')  #write.csv(df,"uk_rain.csv")
約等於R中的write.csv(df,"uk_rain.csv"),其中df是資料集的名稱,跟前面的read_csv不太一樣。

更一般的表現形式:

pd.read_table("./marks.csv", sep=",")


3、txt檔案匯入——np.loadtxt

用numpy中的一個函式可以實現txt檔案的匯入。

np.loadtxt("/caffe/examples/lmdb_test/train/synset.txt", str, delimiter='\t')

4、讀取word文件——docx包

pip install  python-docx
安裝與下載。記住不是直接pip docx
import docx

資料讀入
# 讀取word內容
# 這裡是以段落為單位的,下面用一個for 遍歷所有段落
doc = docx.Document("D:\\test2.docx")
parag_num = 0
for para in doc.paragraphs :
    print(para.text)
    parag += 1  
print ('This document has ', parag, ' paragraphs')
其中doc.paragraphs代表文件的段落,如何輸出每個段落的內容是用:para.text。

資料儲存:

# 使用引數16表示將doc轉換成docx,儲存成docx後才能 讀檔案

doc.SaveAs(r"D:\\test2.docx",16)
doc.Close()
word.Quit()

5 其他一些格式匯入

        f = open('file.txt','r+',encoding='utf-8')#encoding引數可以指定檔案的編碼
            f.readline()#讀一行
            f.readable()#判斷檔案是否可讀
            fr.writable()#判斷檔案是否可寫
            fr.encoding#列印檔案的編碼
            f.read()#讀取所有內容,大檔案時不要用,因為會把檔案內容都讀到記憶體中,記憶體不夠的話,會把記憶體撐爆
            f.readlines()#讀取所有檔案內容,返回一個list,元素是每行的資料,大檔案時不要用,因為會把檔案內容都讀到記憶體中,記憶體不夠的話,會把記憶體撐爆
            f.tell()#獲取當前檔案的指標指向
            f.seek(0)#把當前檔案指標指向哪
            f.write('愛情證書')#寫入內容
            f.fulsh()#寫入檔案後,立即從記憶體中把資料寫到磁碟中
            f.truncate()#清空檔案內容
            f.writelines(['愛情證書','孫燕姿'])#將一個列表寫入檔案中
            f.close()關閉檔案
參考來自:python學習筆記(三):檔案操作和集合


————————————————————————————————————————————————————

七、資料檢視——行列名、檢視

R中常有的兩種方式——$  []:

data$colnames

data["colnames",]

函式使用辦法都是:sum(data)

python中通過 . 傳導式的:

data.sum

1、資料檢視

檢視資料的前5個,後5個。

data.head(5)

data.tail(5)

在R中為head(data)/tail(data)

2、資料型別

type(data)

3、列數量、行數量 len(R中的length)

len(data)      #行數

len(data.T)  #列數

其中data.T是資料轉置,就可以知道資料的行數、列數。

————————————————————————————————————————

延伸一:遍歷檔案方法

   筆者作為小白在遍歷檔案的時候,看到幾種辦法挺好的:os.listdir  和  os.walk

os.listdir返回的是該資料夾下的所有檔名稱;
os.walk可以返回父資料夾路徑+資料夾下路徑,貌似比較給力。


#!/usr/bin/python
import os
from glob import glob

def printSeparator(func):
    def deco(path):
        print("call method %s, result is:" % func.__name__)
        print("-" * 40)
        func(path)
        print("=" * 40)
    return deco
@printSeparator
def traverseDirByShell(path):
    for f in os.popen('ls ' + path):
        print f.strip()
@printSeparator
def traverseDirByGlob(path):
    path = os.path.expanduser(path)
    for f in glob(path + '/*'):
        print f.strip()
@printSeparator
def traverseDirByListdir(path):
    path = os.path.expanduser(path)
    for f in os.listdir(path):
        print f.strip()
@printSeparator
def traverseDirByOSWalk(path):
    path = os.path.expanduser(path)
    for (dirname, subdir, subfile) in os.walk(path):
        #print('dirname is %s, subdir is %s, subfile is %s' % (dirname, subdir, subfile))
        print('[' + dirname + ']')
        for f in subfile:
            print(os.path.join(dirname, f))
if __name__ == '__main__':
    path = r'~/src/py'
    traverseDirByGlob(path)
    traverseDirByGlob(path)
    traverseDirByListdir(path)
    traverseDirByOSWalk(path)


    1、traverseDirByGlob、traverseDirByOSWalk兩種函式可以拿到帶全部路徑的檔案,類似:

/data/trainlmdb/val/test_female/image_00009.jpg

    2、traverseDirByListdir(path)可以拿到裡面的檔名:
image_00009.jpg


   當然這個函式裡面是print出來的。基於筆者的小白級寫函式方法,筆者改進:

def traverseDirByGlob(path):
    path = os.path.expanduser(path)
    list={}
    i=0
    for f in glob(path + '/*'):
        list[i]=f.strip()
        i=i+1
    return list

   就可以跟其他的def函式一樣return出來。

————————————————————————————————————————

延伸二:pickle模組的基本使用:pkl檔案

 python的pickle模組實現了基本的資料序列和反序列化。通過pickle模組的序列化操作我們能夠將程式中執行的物件資訊儲存到檔案中去,永久儲存;通過pickle模組的反序列化操作,我們能夠從檔案中建立上一次程式儲存的物件

儲存:

#使用pickle模組將資料物件儲存到檔案

import pickle

data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()
讀取:
with open(path, 'rb') as f:
    labels = pickle.load(f)
path是pkl的路徑名

————————————————————————————————————————

延伸三:報錯TypeError: 'str' object is not callable

因為一些函式名字,被用來命名臨時變量了。比如:

len=1
len(data)
TypeError: 'str' object is not callable

len這個函式被之前命名了。

————————————————————————————————————————

延伸四:在元組和list中新增元素

一般新增元素的辦法有用:

用加號 或者 append

兩者的使用效果不同。

append是:list+list = 兩個listlist + 元素 = 一個list

+號是: 元組 + 元組 = 一個元組

list可以使用append,而元組不可以用append新增元素

————————————————————————————————————————

延伸五:去重

1、for迴圈,同時保持原來的位置

ids = [1,2,3,3,4,2,3,4,5,6,1]
news_ids = []
for id in ids:
    if id not in news_ids:
        news_ids.append(id)
print news_ids
保持之前的排列順序。

2、set 可以去重+排序

ids = [1,4,3,3,4,2,3,4,5,6,1]
ids = set(ids)

3、count函式迭代去重

from collections import Counter\

ImagePath = traverseDirByGlob(root_dir)

Path = []
[Path.append(v)  for _,v in  ImagePath.items()]
Duplicate = [ (str(k),str(v)) for k,v in dict(Counter(tuple(Path))).items() if v>1] 
.

延伸七:在Python命令列中使用pip 安裝

get_ipython().system(u'pip2 install -U google-cloud-vision')