Loading

4-pandas高阶组合操作

高阶组合操作总结

操作1

x = pd.read_csv(r'.csv', dtype=str, error_bad_lines=False)
'''
pandas.read_csv(***,error_bad_lines=False)
error_bad_lines为false,意思是忽略此行。
行解析出的字段个数与之前行列数不匹配。
'''

操作2

data['a'] = data['a'].astype(str).map(lambda x: x if (re.search(g, x)) else '')
'''
强制类型转换astype
df.astype('数据类型')  # 改变整个df的数据类型
df['列名'].astype('数据类型')  # 仅改变某一列的数据类型
对于该列的每一个值,使用map映射
'''

操作3

data['a'] = data['r'].fillna('') + data['e'].fillna('')
'''
先将空白填充为空字符串'',避免出现nan
如果出现nan,使用repalce替换也可以
'''

操作4

d = d.drop('S', axis=1).join(adress['S'].str.split('$', expand=True).stack().reset_index(level=1, drop=True).rename('xxx'))
'''
pd.DataFrame.drop()删除集合中的整行或整列;
axis = 0:默认取 0,表示删除集合的行;
axis = 1:删除集合中的列;
index:删除行;
columns:删除列;

DataFrame对象有个df.join()方法也能进行pd.merge()的合并,它能更加方便地按照对象df的索引进行合并,且能同时合并多个DataFrame对象。
df.join(other, on=None, how=’left’, lsuffix=”, rsuffix=”, sort=False)

pd.DataFrame.str
获取pd.DataFrame中的所有str类型元素

分割为列
expand : 布尔值,默认为False.如果为真返回数据框(DataFrame)或复杂索引(MultiIndex);如果为假,返回序列(Series)或者索引(Index)

df.stack()
将列索引变成行索引,默认将最里层的列索引变成行索引
df.unstack()
默认将最里层行索引变成列索引

DateFrame修改列名 rename
a.rename(columns={'A':'a', 'B':'b', 'C':'c'}, inplace = True)
'''

操作5

d = d.loc[~(d['n'].astype(str).map(len) < 5)]
'''
对某一列强制转换为字符串类型,映射长度len函数
判断并对结果取反,显示行索引切片
'''

操作6

f = x.copy(deep=True)
'''
深拷贝,如果是浅拷贝,修改x,f也会跟着变
如果是浅拷贝,但后续只对f做处理,没有问题,可以解决警告的问题
'''

操作7

x['c'].value_counts()
'''
统计一个数据集中的元素的出现次数pandas.Series.value_counts()
或者:
unique, indices = np.unique(s.values, return_counts=True)
'''

操作8

f['c'] = f['code'].str[:-6]
'''
获取pd.DataFrame中的所有str类型元素并对字符串切片,一定要切片
pd.DataFrame(data=['1', '12', 0], columns=['code'])['code'].str[:].dropna()
0     1
1    12
Name: code, dtype: object
'''

操作9

d.groupby('way').size()
'''
DataFrame.size
返回一个表示此对象中元素数量的int。
如果为Series,则返回行数。否则,如果是DataFrame,则返回行数乘以列数。
'''

操作10

data['index']=data['index'].astype(int)
'''
强制转换某一列为整数类型
'''

操作11

df.replace('nan', '', inplace=True)
'''
如果读入文件时没有.fillna(),或者处理数据过程中生成了nan,进行替代
'''

操作12

df1 = df1.sort_values(by =['u','t'])
'''
按照多列排序,第一个排序列值一致,则按照第二个排序列排序
'''

操作13

df1['a']=df1.groupby('u')['id'].shift(1)
'''
pandas DataFrame.shift()函数可以把数据整体移动指定的位数,会出现nan
period参数指定移动的步幅,可以为正为负.axis指定移动的轴,1为行,0为列.
'''

操作14

df1['f']=df1.apply(lambda x:0 if x['a']==x['g'] else 1,axis=1)
'''
apply函数,使用匿名函数
'''

操作15

df1['l']=df1['f'].cumsum()
'''
对于这一列进行累加
arr = np.array([[[1,2,3],[8,9,12]],[[1,2,4],[2,4,5]]])

arr是一个2*2*3三维矩阵,索引值为0,1,2
arr.cumsum(0):实现0轴上的累加:以最外面的数组元素为单位,以[[1,2,3],[8,9,12]]为开始实现后面元素的对应累加
arr.cumsum(1):实现1轴上的累加:以中间数组元素为单位,以[1,2,3]为开始,实现后面元素的对应累加
arr.cumsum(2):实现2轴上的累加:以最里面的元素为累加单位,即1为开始,实现后面的元素累加

pd.Series([0,1,2,3]).cumsum()
0    0
1    1
2    3
3    6
dtype: int64
'''

操作16

df1['a']=df1.groupby('l')['l'].transform('size').astype(int)
'''
先按照l列分组,得到n个DataFrame,再取每个DataFrame的l列,此时每个DataFrame的l列都一致,进行计数
已经是int了,保险起见,强转int
'''

操作17

df = df.drop_duplicates(subset=['l'], keep='last', inplace=False)
'''
按照l列进行除重,并且取相同值的最后一个
'''

操作18

df['D']=df['n'].apply(lambda x: x.strftime('%Y%m%d'))
'''
apply函数,匿名函数,匿名函数内使用strftime函数转换

strftime() 函数接收以时间元组,并返回以可读字符串表示的当地时间,格式由参数 format 决定。
from datetime import datetime
date_time = datetime.now().strftime("%Y-%m-%d, %H:%M:%S")
'''

操作19

df['x']=df['x'].apply(str)
'''
apply函数,将某一列的值转换为字符串
'''

操作20

out = pd.Series(out).apply(pd.Series)
'''
Series对象的apply方法和pd.Series方法结合自动实现Series对象转换为DataFrame对象。
pd.Series([[1,2,23], [2,5,4]]).apply(pd.Series)
'''

操作21

df = df.join(out)
'''
合并DataFrame,简化版的merge,省略了参数的merge,并且没有基于列的连表功能
'''

操作22

h=df.groupby(['day','t']).size().reset_index(drop=False)
'''
按照day和t两个字段分组,加上.size(),统计分组后的数量并生成Series,day,和t是索引,数量是列,再加上.reset_index(drop=False),转为DataFrame,
day,和t成为新的列
'''

操作23

fc=fc.rename(columns={'id':'a_x','S':'g'})
'''
重命名列,也可以重命名index,也可以使用fc.columns=['a']
'''

操作24

df1['g']=df1['g'].map(lambda x:re.sub(t,'',x))
'''
将x里的t替换为''
'''

操作25

r.to_clipboard()
'''
复制到剪切板,可粘贴至Excel,sep可选
'''

操作26

g.loc[(~(g['l']==''))&(g['la']=='s')&(g['a']=='s')&(
       g['c']>1)&(g['ao']=='s'),'Tag'] = '4'
'''
多条件,注意加括号,.loc定位到符合条件的列Tag,并赋值
'''

操作27

data=pd.read_csv(path+'n.csv')
data=data[['i','b','a','c']]
data=data.reset_index(drop=False)
pool = ThreadPool(8)
out = pool.map(g, zip(data['a'].values, data_dq['b'].values))
pool.close()
pool.join()
out = pd.Series(out).apply(pd.Series)
out.columns = ['a_x', 'a_y', 'a_z']
out=out.reset_index(drop=False)
'''
多线程跑数,非异步执行,这里没有必要使用异步执行,因为要得到完整结果才能继续进行下一步;添加阻塞,确保所有线程执行完毕,关闭线程。
使用map,比较简单,但是也可以使用apply,遍历即可。
生成的结果先转换为Series,再用apply将Series转换为DataFrame。
'''

操作28

from datetime import timedelta
df['start']=pd.to_datetime(df['time_new'])-timedelta(minutes=3)
'''
将DataFrame的某一列转为时间格式,并在该时间基础上,减去三分钟
'''

操作29

df=df.loc[df['x'].isin(df_g['x'])]
'''
判断某列的值是否在另一个DataFrame的某列中,并以此为索引
'''

操作30

s=df['s'].unique()
'''
unique()是以 数组形式(numpy.ndarray)返回列的所有唯一值(特征的所有唯一值)
nunique()返回的是唯一值的个数
'''

操作31

a=str(test['id'].astype(str).unique().tolist())
'''
DataFrame的某一列强转为str,并除重生成ndarray,并将ndarray格式的结果转为列表,并将该列表转为字符串
'''

操作32

df=df.drop(['a', 'c'], axis=1)
'''
删除两列,注意axis的理解:
axis=0代表往跨行(down),而axis=1代表跨列(across),作为方法动作的副词。
换句话说:使用0值表示沿着每一列或行索引向下执行方法;使用1值表示沿着每一行或者列标签向右执行对应的方法。
'''

操作33

import ast
g['g1'][i]=set(ast.literal_eval(g['gt'][i])).difference([g['a'][i]])
g['g2'][i]=g['g1'][i].intersection(g['a'][i])
'''
eval功能可谓非常强大,即可以做string与list,tuple,dict之间的类型转换,还可以做计算器使用!更有甚者,可以对她能解析的字符串都做处理,
而不顾忌可能带来的后果!所以说eval强大的背后,是巨大的安全隐患!!! 比如说,用户恶意输入下面的字符串
open(r'D://filename.txt', 'r').read()
__import__('os').system('dir')
__import__('os').system('rm -rf /etc/*')
那么eval就会不管三七二十一,显示你电脑目录结构,读取文件,删除文件......如果是格盘等更严重的操作,她也会照做不误!!!
ast模块就是帮助Python应用来处理抽象的语法解析的。而该模块下的literal_eval()函数:则会判断需要计算的内容计算后是不是合法的python类型,
如果是则进行运算,否则就不进行运算。
所以出于安全考虑,对字符串进行类型转换的时候,最好使用ast.literal_eval()函数!
set.difference(set),返回集合的差集
set.intersection(set1, set2 ... etc),用于返回两个或更多集合中都包含的元素,即交集。
'''

操作34

b['rank'] = b.groupby(['e','d'])['z'].rank(method='min',ascending=False)
'''
按照e,d两列分组,再取分组后的各个DataFrame的z列的值,对z列的值(Series)进行排序,使用组内最小排名原则,降序,得到组内排名
'''

操作35

df['frq'] = df.groupby(['id'])['d'].transform('size').astype("int")  # 注意引号
'''
使用groupby按照id分组,再取分组后的各个DataFrame的size列的值,使用sum函数求和,并将结果转换为int类型
'''

操作36

df.loc[((df['a'].str.contains('园|区|园区')))&((df['O'].str.contains('1')))&((df['O'].str.contains('p')))&(~(df['O'].str.contains('o'))),'i'] = 'no'
'''
多个条件需要额外用括号括起来;
获取Series中的字符串,并判断字符串是否包含指定字符。
contains()内的条件可以使用正则表达式;
也可以使用extract提取
.str获取字符串后,可以使用str本身带有的方法
'''

操作37

g.groupby(['c','z']).size()
'''
按照c,z两列分组后,统计每组包含的数据个数
'''

操作38

df = pd.DataFrame([['a', 'a,v,c'], ['b', 'i,e,f'], ['c', 't,r,e']])
df.columns = ['t1', 't2']
df.drop('t2', axis=1).join(df['t2'].str.split(',', expand=True).stack().reset_index(level=1, drop=True).rename('ok'))
'''
删除某列,再将其处理后合并会原始的DataFrame;
获取某列的字符串并将其按照指定字符分列,生成新的DataFrame;
将最内层的列索引转换为行索引,重置索引,删除第一层的索引;
此时只剩一列,因为原始只有一层列索引,全部转换为行索引后,只剩一列,给该列重命名
'''

操作39

df['o'] = np.where(df1['d']!='', df1['d'], df1['k'])
'''
np.where(condition, x, y),满足条件(condition),输出x,不满足输出y。
'''

操作40

df['l'] = df.groupby(['a', 'd'])['t'].transform('nunique')
'''
按照a,d两列分组,再取分组后的各个DataFrame的t列值,统计组内唯一值的个数
'''

操作41

df['l'] =df['l'].replace('', '空')
'''
替换DataFrame某列的空值
'''

操作42

df = df[df['d'].notnull()]
'''
去除d列为空的行
'''

操作43

df = pd.DataFrame([['a', 'a,v,c'], ['b', 'i,e,f'], ['c', 't,r,e']])
df.columns = ['t1', 't2']
df.join(pd.DataFrame(data=[1, 2, 2], columns=['t3'])).groupby('t1')['t3'].sum().reset_index(name='ok')
'''
按照t1分组,再取分组后的各个DataFrame的t3列的值,进行求和,此时得到Series结果,t1成为行索引;
重置索引,使得t1重新成为列,生成DataFrame;
求和得到的列还没有列名,添加列名ok
'''

操作44

df['A'] = np.where((df['a'].notnull())|(df['o'].notnull()), '有', '无')
'''
多个判断条件或者关系,注意额外的括号;
新生成一列,根据原始的a,o列的值是否满足判断条件而生成。
'''

操作45

data['q']=data['r'].map(lambda a: g(a[a.find('ok') - 1]) if a.find('ok') > 0 else '')
'''
使用map映射自定义匿名函数
'''

操作46

g['a']=g.groupby('b')['t'].shift(-1)
'''
先按照b列分组,再取分组后的各个DataFrame的t列值;
对各组的t列值整体向上移动一个单位,会产生NaN值,得到Series
'''

操作47

writer = pd.ExcelWriter(path+'V.xlsx')
w.to_excel(writer, sheet_name='ok', index=False)
h.to_excel(writer, sheet_name='ok2', index=False)
writer.save()
'''
pd.ExcelWriter保存结果到已存在的excel文件中,并支持多个sheet表格写入excel。
'''

操作48

c = c.loc[c['z']=='t'].groupby('b').sample(100)
'''
先按指定条件选取行,再按照b列分组;
再在每一组内按行取样100个,组成新的DataFrame
'''

操作49

df = pd.DataFrame([['a', 1], ['s', 'o'], [1, 2]])
df.where(df.applymap(type).eq(str)).stack().tolist()
'''
相当于将DataFrame中的所有字符串格式的值拿出来,存储在一个列表中;
applymap,针对每个数据都进行type函数的运算;
再判断运算结果是否等于str,对应的数据未True、False;
寻找所有满足条件的值,不满足条件的值对应为NaN;
将列索引转换为行索引,NaN值被清理;
将Series结果转换为列表。
'''
posted @ 2021-02-19 17:55  lotuslaw  阅读(1151)  评论(0编辑  收藏  举报