一、如何在列表,字典,集合中根據(jù)條件篩選數(shù)據(jù)?
創(chuàng)新互聯(lián)成立于2013年,是專(zhuān)業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目做網(wǎng)站、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元無(wú)極做網(wǎng)站,已為上家服務(wù),為無(wú)極各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18980820575
問(wèn)題1:
如何過(guò)濾掉列表[3,9,-1,10,20,-2]中的負(fù)數(shù)?
解決方法:
在Python中可以使用函數(shù)式編程,列表解析,字典解析集合解析等方式進(jìn)行篩選。
1)最通常的方法:迭代
data = [3,9,-1,10,20,-2]res = []for x in data: if(x = 0): res.append(x)print(res)
2)使用filter函數(shù)
from random import randintdata = [randint(-10,10) for x in range(10)] #在-10到10之間隨機(jī)生成10個(gè)隨機(jī)數(shù)newdata = list(filter(lambda x: x = 0, data))print(newdata)
注意Python3中的filter函數(shù)返回的對(duì)象從列表改為了Iterator(迭代器),因此如果想返回一個(gè)列表,就要加上list()
3)列表解析
newdata2 = [x for x in data if x = 0]print(newdata2)
結(jié)果和使用filter函數(shù)相同,但是使用列表解析所需的時(shí)間要比使用filter快很多,所以首選的方式就是列表解析,另外這兩種方式都遠(yuǎn)快于迭代的方式。(推薦閱讀:Python零基礎(chǔ)入門(mén)在線網(wǎng)課)
問(wèn)題2:
如何篩選出字典中值高于90的項(xiàng)?
解決方法:
from random import randintdic = {x: randint(60,100) for x in range(1,11)} #隨機(jī)生成學(xué)號(hào)1到10的學(xué)生成績(jī)newdic = {k:v for k,v in dic.items() if v = 90} #同時(shí)迭代鍵和值,Python3中的iteritems變?yōu)閕temsprint(newdic)
問(wèn)題3:
如何篩選出集合{77,89,32,29,33}中能被3整除的元素?
解決方法:
s = {77,89,32,29,33}news = {x for x in s if x % 3 == 0}print(news)
二、如何為元組中的每個(gè)元素命名,提高程序的可讀性?
實(shí)際案例:
如學(xué)生信息管理系統(tǒng)中數(shù)據(jù)為固定格式:
(名字,年齡,性別...)
學(xué)生數(shù)量很大,為了減少存儲(chǔ)開(kāi)銷(xiāo),對(duì)每個(gè)學(xué)生信息采用元組表示:
(‘jam’,16,’male’)
(‘tom’,18,’male’)
(‘july’,19,’female’)
...
訪問(wèn)元組時(shí),需要使用索引(index)來(lái)訪問(wèn),
如一個(gè)學(xué)生元組為student = ('jam',19,'male'),那么想要訪問(wèn)其名字時(shí)要使用student[0],訪問(wèn)其性別時(shí)要使用student[2]
由此帶來(lái)的問(wèn)題是大量的索引會(huì)降低程序的可讀性,
那么如何來(lái)解決這個(gè)問(wèn)題呢?
有兩種解決方案:
方案1:定義枚舉類(lèi)型,也就是定義一系列數(shù)值常量
NAME = 0AGE = 1SEX = 2# NAME,AGE,SEX = range(1,4)student = ('jam',19,'male')print(student[NAME])print(student[AGE])
方案2:使用標(biāo)準(zhǔn)庫(kù)中collections.namedtuple替代內(nèi)置的tuple
from collections import namedtupleStudent = namedtuple('student',['name','age','sex']) #相當(dāng)于創(chuàng)建了一個(gè)命名元組類(lèi),第一個(gè)參數(shù)是元組的名字,第二個(gè)參數(shù)是其屬性s1 = Student('jam',18,'male') #可以直接傳參s2 = Student(name='tom',age=20,sex='male') #也可以通過(guò)關(guān)鍵字傳參print(s1.name) #通過(guò)屬性來(lái)訪問(wèn)print(s2.age)
注意:這種發(fā)方法并不是裝飾器最常用的功能,但是在降低代碼重復(fù)上可謂是首屈一指。比如:如果不使用裝飾器,上述代碼可能會(huì)很多:
當(dāng)然,這里也有一個(gè)潛在的風(fēng)險(xiǎn),就是當(dāng)裝飾器包裹的函數(shù)已經(jīng)用了debug作為參數(shù)名,那么裝飾器這里將會(huì)報(bào)錯(cuò),所以要添加額外的一些判斷來(lái)完善代碼:
最后還剩下一部分比較難理解的地方,我將理解的注釋在每行代碼上方,這個(gè)問(wèn)題就是,在打印被修飾函數(shù)的參數(shù)簽名時(shí),其實(shí)并不能正確顯示參數(shù)簽名,原因是因?yàn)楸粀rapper修飾過(guò)后的函數(shù)實(shí)際上應(yīng)該使用的是wrapper的參數(shù)簽名表,例如:
所以,接下來(lái),完成最后最難的一步:
下面是筆者的個(gè)人理解: 把計(jì)算出的值存在函數(shù)內(nèi)部(當(dāng)然不止尾遞歸)是其計(jì)算方法,從而不用在棧中去創(chuàng)建一個(gè)新的,這樣就大大節(jié)省了空間。函數(shù)調(diào)用中最后返回的結(jié)果是單純的遞歸函數(shù)調(diào)用(或返回結(jié)果)就是尾遞歸。
實(shí)例還是和筆者的上一篇文章相同,建議讀者閱讀 Python —— 遞歸
常規(guī)遞歸階乘:
我們來(lái)看一下執(zhí)行過(guò)程:
但是如果把上面的函數(shù)寫(xiě)成如下形式:
我們?cè)倏聪聢?zhí)行過(guò)程:
很直觀的就可以看出,這次的 factorial 函數(shù)在遞歸調(diào)用的時(shí)候不會(huì)產(chǎn)生一系列逐漸增多的中間變量了,而是將狀態(tài)保存在 acc 這個(gè)變量中。而這種形式的遞歸,就叫做尾遞歸。
常規(guī)遞斐波那契數(shù)列:
而尾遞歸:
一下子就充滿了逼格,還高效了許多,何樂(lè)而不為呢!
變量可以指向函數(shù),函數(shù)的參數(shù)可以接收變量,那么函數(shù)可以接收另一個(gè)函數(shù)作為參數(shù),這種函數(shù)稱(chēng)為高階函數(shù)。
1、把函數(shù)作為實(shí)參;2、把函數(shù)作為返回值。
python高階函數(shù)有哪些?
map函數(shù)
map()是python內(nèi)置的高階函數(shù),它接收兩個(gè)參數(shù),一個(gè)是函數(shù),一個(gè)是序列,map將傳入的函數(shù)依次作用到序列的每個(gè)元素,并且把結(jié)果作為新的列表返回。
filter函數(shù)
filter()同樣也是接收一個(gè)函數(shù)和一個(gè)序列,和map()不同的是,filter函數(shù)把傳入的函數(shù)依次作用于每個(gè)元素,然后返回返回值是True的元素。
reduce函數(shù)
reduce()把一個(gè)函數(shù)作用到一個(gè)序列上,這個(gè)函數(shù)必須接收兩個(gè)參數(shù),reduce把結(jié)果和序列的下一個(gè)元素做累積計(jì)算。
lambda函數(shù)
lambda()有時(shí)候傳參數(shù)時(shí)不需要顯示自定義的函數(shù),直接傳入匿名函數(shù)更方便;冒號(hào)前面的X,y表示函數(shù)參數(shù),匿名函數(shù)不需要擔(dān)心函數(shù)名的沖突,匿名函數(shù)也是一個(gè)函數(shù)對(duì)象,可以吧匿名函數(shù)賦值給一個(gè)變量,再利用變量來(lái)調(diào)用函數(shù),匿名函數(shù)也可以作為返回值返回。
sorted函數(shù)
sorted()作為python內(nèi)置高階函數(shù)之一,其功能是對(duì)序列(列表、元組、字典、集合、字符串)進(jìn)行排序。
這是漫長(zhǎng)的一周,本周完成了Python的進(jìn)階模塊,主要是pandas、numpy、matplotlib、seaborn、pyecharts這些模塊的學(xué)習(xí)以及一個(gè)實(shí)際的案例:商品銷(xiāo)售情況分析,之前一直覺(jué)得課程難度不夠,但到這一周難度就大大提高了。尤其是案例練習(xí)中的RFM模型和用戶生命周期建立,看懂不難但是自己寫(xiě)一直出錯(cuò),在不斷出錯(cuò)不斷嘗試中知識(shí)得到了積累,另外可視化部分沒(méi)有什么練習(xí)題,希望后面可以加上一些這方面的練習(xí),接下來(lái)分模塊來(lái)總結(jié)一下學(xué)習(xí)的內(nèi)容。
重新設(shè)置索引:df.set_index()
Series格式轉(zhuǎn)換為DataFrame:df.to_frame()
文件讀?。簆d.read_csv(filepath, header = 0,skiprows=[1,2])?
使用位置做索引:df.loc[0]????????使用列表做索引:df.loc[[0,1,2]]
使用切片做索引:df.loc[0:4]????????使用bool類(lèi)型索引:df[df['年齡']30]
loc 是基于索引值的,切片是左閉右閉的
iloc 是基于位置的,切片是左閉右開(kāi)的
修改列索引:df.rename(columns={'姓名':'name', '年齡':'age'},inplace=True)
替換一個(gè)值:df.replace({'name':{'小明':'xiaoming'}},inplace=True)
對(duì)數(shù)據(jù)進(jìn)行排序:df.sort_values('age')
累加求和:df.cumsum(0)
刪除列:del df['player']?????????刪除行:df.drop(labels=0)?labels 是行列的名字
數(shù)據(jù)拼接:pd.concat([left,right],axis=1)
# 指定列進(jìn)行關(guān)聯(lián),默認(rèn)是 inner join ????result = pd.merge(left,right,on='key')
#多個(gè)關(guān)聯(lián)條件:result = pd.merge(left, right, on=['key1', 'key2'])
#左連接:result = pd.merge(left, right, how='left', on=['key1', 'key2'])
# 列名不一樣的關(guān)聯(lián):pd.merge(left,right,left_on = ['key1','key2'],right_on = ['key3','key4'])
#單個(gè)分組:groups = df.groupby('district')
# 作用多個(gè)聚合函數(shù):groups.agg([np.mean,np.sum,np.std])
# 針對(duì)具體列聚合 groups.age.agg([np.mean,np.sum,np.std])
# 不同列不同聚合函數(shù) groups.agg({"age":np.mean,"novip_buy_times":np.sum})
分組后該列值求和顯示:groups['vip_buy_times'].transform('sum')
通常用于求占比:transform(lambda x: x /sum(x))
# 填充指定值:np.full([3,4],1)
# 起始為10,5為步長(zhǎng),30為結(jié)尾取不到:np.arange(10, 30, 5)
#隨機(jī)矩陣:np.random.random((2,3))
# 平均劃分:np.linspace( 0, 2*pi, 100 )
# 類(lèi)型及轉(zhuǎn)換:vector.astype('float')
# 多維變一維:matrix.ravel()
# 矩陣的擴(kuò)展:a = np.arange(0, 40, 10)? ? b = np.tile(a, (3, 5))? ? # 行變成3倍,列變成5倍
# 水平拼接:np.hstack((a,b))? 豎直拼接:np.vstack((a,b))
# 豎直分割:np.hsplit(a,3)? ? #水平分割:np.vsplit(a,3)
8. Select the data in rows [3, 4, 8] and in columns ['animal', 'age'].
A:df.loc[df.index[[3,4,8]],['animal','age']]
行采用位置,列采用普通索引,這里利用index函數(shù)將位置變化為具體的普通索引,再利用loc函數(shù)
19. The 'priority' column contains the values 'yes' and 'no'. Replace this column with a column of boolean values: 'yes' should be True and 'no' should be False
A1:df['priority'].replace(['yes','no'],[True,False],inplace=True) 用replace函數(shù)替換
A2:df['priority'] = df['priority'].map({'yes': True, 'no': False}) 用map函數(shù)替換
最大最小值的索引:df.idxmax、df.idxmin
找出最大最小的前N個(gè)數(shù):nlargest()和nsmallest()?
將原表分組 并設(shè)置分段區(qū)間 pd.cut(df['A'], np.arange(0, 101, 10))
resample函數(shù) 日期重采樣:s.resample('M').mean()
TimeGrouper 重組:s.groupby(pd.TimeGrouper('4M')).idxmax()
split 分割函數(shù):temp = df['From_To'].str.split('_', expand=True) True為DataFrame
兩個(gè)DataFrame拼接用join:df = df.join(temp)
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei'] #用來(lái)正常顯示中文標(biāo)簽
plt.rcParams['axes.unicode_minus']=False #用來(lái)正常顯示負(fù)號(hào)
%matplotlib inline 直接顯示
折線圖:plt.plot(x,y,color = 'r')
柱狀圖:plt.bar(x,y)? plt.barh(x,y) 多個(gè)bar x設(shè)置不同 堆積圖 bottom設(shè)置不同
散點(diǎn)圖:plt.scatter(x, y, c=colors, alpha=0.5, s = area)
直方圖:plt.hist(a,bins= 20) bin代表分隔的最小單位
plt.legend() 顯示圖例
for a,b in zip(X+W[i],data[i]):
plt.text(a,b,"%.0f"% b,ha="center",va= "bottom") 添加數(shù)據(jù)標(biāo)簽
plt.annotate('注釋文本',xy=(1, np.sin(1)),xytext=(2, 0.5), fontsize=16,arrowprops=dict(arrowstyle="-")) 添加注釋文本
plt.xlabel("Group") x軸標(biāo)題
plt.ylabel("Num") y軸標(biāo)題
fig, axes = plt.subplots(nrows=2, ncols=2,facecolor='darkslategray')? 繪制多個(gè)圖形
axes[0,0] axes[0,1] axes[1,0] axes[1,1]
pylab.rcParams['figure.figsize'] = (10, 6) # 調(diào)整圖片大小
動(dòng)態(tài)展示圖表
from pyecharts.charts import Bar
from pyecharts import options as opts
** pyecharts 繪圖的五個(gè)步驟:**
創(chuàng)建圖形對(duì)象:bar = Bar()
添加繪圖數(shù)據(jù):bar.add_xaxis(["襯衫", "毛衣", "領(lǐng)帶", "褲子", "風(fēng)衣", "高跟鞋", "襪子"])
? ? ???????????????? bar.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
? ? ? ? ? ? ? ? ? ? ?bar.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
配置系列參數(shù):對(duì)標(biāo)簽、線型等的一些設(shè)置
配置全局參數(shù):bar.set_global_opts(title_opts=opts.TitleOpts(title="銷(xiāo)售情況"))
渲染圖片:生成本地 HTML 文件 bar.render("mycharts.html")? bar.render()
notebook 渲染:bar.render_notebook()
bar = (Bar()
.add_xaxis(["襯衫", "毛衣", "領(lǐng)帶", "褲子", "風(fēng)衣", "高跟鞋", "襪子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.set_global_opts(title_opts=opts.TitleOpts(title="某商場(chǎng)銷(xiāo)售情況"))
)
bar.render_notebook()
柱狀圖:Bar()
條形圖:bar.reversal_axis() #翻轉(zhuǎn)XY軸,將柱狀圖轉(zhuǎn)換為條形圖
折線圖:from pyecharts.charts import Line? line=Line()
餅圖:from pyecharts.charts import Page, Pie????Pie()?
轉(zhuǎn)換日期類(lèi)型:df['order_dt']=pd. to_datetime (df.order_dt,format="%Y%m%d")
將日期轉(zhuǎn)換為月為單位:df['month']=df.order_dt.values. astype('datetime64[M]') 所有日期顯示為當(dāng)月第一天
去除日期單元值:order_diff/ np.timedelta64(1,'D')
過(guò)濾部分極值:grouped_user.sum() .query('order_products100') .order_amount
數(shù)據(jù)透視表:rfm=df.pivot_table( index ='user_id', values =['order_products','order_amount'], aggfunc ={'order_amount':'sum','order_products':'sum'})
map() 方法是pandas.series.map()方法, 對(duì)DF中的元素級(jí)別的操作, 可以對(duì)df的某列或某多列
applymap(func) 也是DF的屬性, 對(duì)整個(gè)DF所有元素應(yīng)用func操作
purchase_r=pivoted_counts.applymap(lambda x: 1 if x1 else np.NaN if x==0 else 0)
apply(func) 是DF的屬性, 對(duì)DF中的行數(shù)據(jù)或列數(shù)據(jù)應(yīng)用func操作,也可用于Series
apply(lambda x:x.cumsum()/x.sum())? ? 累計(jì)占比
apply(lambda x:x/x.sum(),axis=0)? ? ?每一列中每行數(shù)據(jù)占比
下周開(kāi)始進(jìn)入數(shù)據(jù)分析思維的課程,很期待后面的課程以及項(xiàng)目,加油!