回復(fù) 紅包 可以領(lǐng)程序員專屬紅包封面
Pandas是一個強(qiáng)大的分析結(jié)構(gòu)化數(shù)據(jù)的工具集;它的使用基礎(chǔ)是Numpy(提供高性能的矩陣運算);
用于數(shù)據(jù)挖掘和數(shù)據(jù)分析,同時也提供數(shù)據(jù)清洗功能。
它是一種類似于一維數(shù)組的對象,是由一組數(shù)據(jù)(各種NumPy數(shù)據(jù)類型)以及一組與之相關(guān)的數(shù)據(jù)標(biāo)簽(即索引)組成。
僅由一組數(shù)據(jù)也可產(chǎn)生簡單的Series對象
默認(rèn)index是數(shù)字
import pandas as pd
import numpy as np
# 自定義打印的函數(shù),方便后面調(diào)試
def _print(s: str, *args, pad=20):
print('\n', s.center(pad, '-'))
for i in args:
print(i)
infoLi = ['jack', 18, '180CM']
serLi = pd.Series(data=infoLi)
_print('list構(gòu)建Series', serLi)
serLi = pd.Series(data=infoLi, index=list('abc'))
_print('list構(gòu)建Series,并指定index', serLi)
index為字典的key
infoDic = {'name': 'jack', 'age': 18, 'height': '180CM'}
serDic = pd.Series(data=infoDic)
_print('字典構(gòu)建Series', serDic)
infoLi = serLi.tolist()
_print('Series轉(zhuǎn)換為list', infoLi)
infoDic = serDic.to_dict()
_print('Series轉(zhuǎn)換為dict', infoDic)
df = pd.DataFrame(data=serDic)
_print('Series轉(zhuǎn)換為DataFram', df)
df = pd.DataFrame(data=serDic, columns=['信息'])
_print('Series轉(zhuǎn)換為DataFram,并指定列名', df, pad=30)
s = pd.Series(data=['001', '002'], index=list('ab'))
_print('構(gòu)建Series', s)
sastype = s.astype(int)
_print('使用astype函數(shù)修改數(shù)據(jù)類型', sastype)
map函數(shù)可以將一個匿名函數(shù)作用于所有的數(shù)據(jù)上
相當(dāng)于遍歷了一遍Series,對每一個值執(zhí)行了float()方法
smap = s.map(lambda x: float(x))
smap = s.map(float)
_print('使用map修改數(shù)據(jù)類型', smap)
使用concat將一個Series追加原Series后面
sCon = pd.Series(data=['003', '004'], index=['c', 'd'])
s = pd.concat([s, sCon])
_print('concat追加新元素', s)
> 指定axis=1,橫向追加,兩個Series橫向追加會變成DataFrame
df = pd.concat([s, sCon], axis=1)
_print('concat追加新元素,并指定axis=1', df)
DataFrame是Pandas中的一個表格型的數(shù)據(jù)結(jié)構(gòu),包含有一組有序的列,每列可以是不同的值類型(數(shù)值、字符串、布爾型等),DataFrame即有行索引也有列索引,可以被看做是由Series組成的字典。
> 如果字典的key不是列表,需要指定index,或者使用items()取出k,v
infoDic = {'name': 'jack', 'age': 18, 'height': '180CM'}
df = pd.DataFrame(data=infoDic, index=[0])
_print('指定index=[0]', df)
# 使用items()取出k,v
df = pd.DataFrame(data=list(infoDic.items()))
_print('使用items()取出k,v', df)
infoDic = {'id': [1, 2], 'name': ['jack', 'rose'], 'age': [18, 18], 'height': ['180CM', '170CM']}
df = pd.DataFrame(data=infoDic)
_print('v是列表', df)
columns也可以不指定
df = pd.DataFrame([[1, 2], [11, 12]], columns=['c1', 'c2'], index=['i1', 'i2'])
_print('使用list創(chuàng)建DataFrame', df)
創(chuàng)建一個np.arange()可以創(chuàng)建一維ndarray,reshape是修改形狀,這里修改成了3行4列的二維ndarray
同樣,直接使用list創(chuàng)建也行
df = pd.DataFrame(np.arange(12).reshape(3, 4))
_print('使用numpy創(chuàng)建DataFrame', df)
index為100個日期,字段內(nèi)容為正態(tài)分布和均勻分布隨機(jī)數(shù)
date_range = pd.date_range(start='2022-01-01', periods=100) # date_rage可以生成各種類型的日期
data = {
'normal': np.random.normal(loc=0, scale=1, size=100), # 正態(tài)分布
'uniform': np.random.uniform(low=0, high=1, size=100) # 均勻分布
}
df = pd.DataFrame(data=data, index=date_range)
_print('復(fù)雜DataFrame', df)
df = pd.read_csv('./IMDB-Movie-Data.csv')
查看dataframe的描述信息
_print('info', df.info)
查看數(shù)據(jù)類型
_print('dtypes:', df.dtypes)
df['Title'].astype('string')
查看后面幾行
_print('tail', df.tail(10))
查看數(shù)據(jù)前幾行
_print('head', df.head(10))
_print('取單列', df['Rank'])
注意是兩個中括號
_print('取多列', df[['Rank', 'Title', 'Metascore']])
可以將列表的切片思想直接拿過來用
_print('按行取', df[0:2])
可同時按照行和列進(jìn)行取值
_print('loc', df.loc[0:2, 'Rank':'Metascore'])
可同時按照行和列進(jìn)行取值,使用數(shù)字下標(biāo)
_print('iloc', df.iloc[0:2, 1:3])
所有字符串操作均可以,這里只列舉幾個
_print('字符串操作', df['Title'].head())
_print('str.upper', df['Title'].str.upper())
_print('str.replace', df['Title'].str.replace(' ', '/'))
_print('str.split', df['Title'].str.split(' '))
如果多個條件,每個條件用()括起來,并且用& 或者用|
print(df[(df['Rank'] % 2 == 0)])
print(df[(df['Rank'] < 10) & (df['Metascore'] > 70)])
df = pd.DataFrame(data=[[1, 2]])
df.columns = ['col1', 'col2']
_print('columns修改所有列名:', df)
df.rename(columns={'col1': 'c1'}, inplace=True)
_print('rename修改指定列名:', df)
df.loc[0, 'c1'] = 11
_print('修改指定值:', df)
df = pd.DataFrame(data=np.full((3, 4), np.nan), columns=list('abcd'), index=list('xyz'))
df.loc['x', 'a'], df.loc['y', 'a'], df.loc['x', 'b'] = 1, 2, 3
print(df)
_print('判斷是否為NaN', df.isnull())
_print('判斷是否為NaN', df.isna())
_print('判斷是否不為NaN', df['a'].notnull())
df_f_1 = df.fillna(0)
df_f_2 = df.fillna(method='ffill')
_print('原樣:', df)
_print('使用前一個填充', df_f_2)
print('-----NaN填充為列平均值-----')
for i in df:
if df[i].isna().any():
df[i].fillna(value=df[i].mean(), inplace=True)
print(df)
df = pd.read_csv('./IMDB-Movie-Data.csv')
_print('df', df)
ascending:指定排序方式,na_position:NaN值放在頭還是尾
df.sort_index(inplace=True, ascending=False, na_position='first')
_print('sort_index', df)
by:按照哪個字段排序
df.sort_values(by=['Revenue (Millions)', 'Metascore'], inplace=True, ascending=True, na_position='last')
_print('sort_values', df[['Revenue (Millions)', 'Metascore']].head(20))
_print('info:', df)
df.set_index(keys=['Rank', 'Title'], inplace=True)
_print('使用set_index修改索引列:', df)
df.reset_index(inplace=True)
_print('使用reset_index重置索引列:', df)
left = pd.DataFrame(np.arange(6).reshape(3, 2), columns=['a', 'b'], index=['i1', 'i2', 'i3'])
right = pd.DataFrame(np.arange(4, 10).reshape(3, 2), columns=['c', 'd'], index=['i1', 'i2', 'i23'])
_print('_left', left)
_print('right', right)
將n個datafram進(jìn)行合并,和SQL的邏輯一模一樣
注意:兩個Dataframe的字段名不能相同
# inner 內(nèi)連接,取行索引的交集,不匹配的不展示
inner = left.join(right, how='inner')
_print('inner', inner)
# outer 外連接,取行索引的并集,不匹配的顯示NaN
outer = left.join(right, how='outer')
_print('outer', inner)
# left 左連接,使用左邊df的行索引,左側(cè)全展示,右側(cè)不匹配的顯示NaN
outer_l = left.join(right, how='left')
_print('outer_l', outer_l)
# right 右連接,使用右邊df的行索引,右側(cè)全展示,左側(cè)不匹配的顯示NaN
outer_r = left.join(right, how='right')
_print('outer_r', outer_r)
left左表,right右表,left_on,right_on兩個表的關(guān)聯(lián)字段
merge = pd.merge(left=left, right=right, left_on='b', right_on='d', how='left')
_print('merge', merge)
SQL的聚合函數(shù)都可以使用
df = pd.read_csv('./IMDB-Movie-Data.csv')
_print('df', df)
_print('sum', df.sum())
_print('mean', df.mean())
_print('count', df.count())
_print('min', df.min())
_print('max', df.max())
一次性使用多個聚合函數(shù)
agg = df.agg(['mean', 'sum', 'max'])
_print('agg', agg)
9.2. agg不同字段不同函數(shù)
agg = df.agg({'Rank': ['sum', 'min'], 'Metascore': ['max', 'min']})
_print('agg不同字段不同函數(shù)', agg)
df = pd.DataFrame(np.random.randint(1, 10, size=32).reshape(8, 4),
index=pd.date_range('12/1/2020', periods=8),
columns=['A', 'B', 'C', 'D'])
_print('開窗', df)
# 每3個數(shù)求一次均值
df['A_rolling'] = df['A'].rolling(window=3).mean()
_print('rolling', df)
expanding 又叫擴(kuò)展窗口函數(shù),擴(kuò)展是指由序列的第一個元素開始,逐個向后計算元素的聚合值
# 從1個開始,每次都累加上之前的值
df['A_expanding'] = df['A'].expanding(min_periods=2).sum()
_print('expanding', df)
移動函數(shù),可以獲得某列前后n行的值,可以計算同比環(huán)比
# 獲得A列后面一個的值
df['A_shift+1'] = df['A'].shift(periods=1)
_print('shift', df)
# 獲得A列前面一個的值
df['A_shift-1'] = df['A'].shift(periods=-1)
_print('shift', df)
列轉(zhuǎn)行就是把列名提到行里面去
df = pd.DataFrame([['張三', 10, 20], ['李四', 30, 40]], columns=['姓名', '語文', '數(shù)學(xué)'])
print(df)
需要將不變的列設(shè)置為索引(原始字段為姓名,語文,數(shù)學(xué),轉(zhuǎn)換后為姓名,科目,成績。姓名字段不變)
df_stack = df.set_index('姓名').stack()
_print('df_stack', df_stack)
df_stack = df_stack.reset_index() # 重置索引
_print('df_stack重置索引', df_stack)
df_stack.columns = ['姓名', '科目', '成績']
_print('df_stack,設(shè)置列名', df_stack)
id_vars:列轉(zhuǎn)行后,不變的那一列
value_vars:列轉(zhuǎn)行后,需要變動的那些列的列名
var_name:列轉(zhuǎn)為行后,value_vars所屬的字段名 http://qn.nulls.cn/202211181539833.png
value_name:列轉(zhuǎn)為行后,新表的值那一列的列明
df_melt = df.melt(id_vars='姓名', value_vars=['語文', '數(shù)學(xué)'], var_name='科目', value_name='成績')
_print('df_melt', df_melt)
行轉(zhuǎn)列就是把行里的值提成列名
tmp = pd.DataFrame({'姓名': ['張三', '李四', '王五', '張三', '李四', '王五', '張三', '李四', '王五'],
'科目': ['英語', '英語', '英語', '數(shù)學(xué)', '數(shù)學(xué)', '數(shù)學(xué)', '語文', '語文', '語文'],
'分?jǐn)?shù)': [90, 60, 70, 80, 98, 80, 85, 90, 75]})
_print('行轉(zhuǎn)列原始數(shù)據(jù)', tmp)
tmp2 = tmp.set_index(['姓名', '科目'])['分?jǐn)?shù)'].unstack().reset_index()
_print('行轉(zhuǎn)列unstack', tmp2)
df = tmp2.rename_axis(columns=None) # 消除科目兩個字
_print('行轉(zhuǎn)列unstack', df)
df = tmp.pivot(index='姓名', columns='科目', values='分?jǐn)?shù)').reset_index().rename_axis(columns=None)
print(df)
df = pd.DataFrame([(1, '總裁室', np.NaN),
(2, '研發(fā)部', 1),
(3, '市場部', 1),
(4, '后端', 2),
(5, '前端', 2),
(6, '大數(shù)據(jù)', 2),
(7, '數(shù)倉開發(fā)', 6),
(8, '數(shù)據(jù)分析', 6)
],
columns=['ID', 'PRODUCTNAME', 'PARENTID'])
print('*' * 100)
def get_order(argid, df):
# 通過ID獲取PARENTID
pid = df.loc[df['ID'] == argid, 'PARENTID']
# print(type(pid), pid) # Series類型
pid = pid.values[0] # 獲取PARENTID的具體值
if pd.isna(pid):
return str(argid)
else:
return get_order(pid, df) + '->' + str(argid)
for i in df.values:
df.loc[df['ID'] == i[0], ['ORDERID']] = get_order(i[0], df)
print(df)
data = [{'word': ['a', 'q', 'a']}, {'word': ['qwe', 'qwe', 'a', 'asd']}, {'word': ['sd']}]
lst = []
for dic in data:
lst.extend(dic['word'])
res = pd.Series(lst) # 轉(zhuǎn)Dataframe也行
res = res.value_counts().to_dict()
print(res)
聯(lián)系客服