1、背景
2019年11月底因需要,使用Python对大众装配线边的数据做了一些处理,由于第一次做处理,有些很不熟悉,故于此记下记录与心得。才学疏浅,望各位指教。
2、常用函数
2.1、local()
在批次读取csv文件时,为批量生成变量名。采用local()函数生成。
names = locals()
n = ['过点信息明细2019.9.23-2019.10.18','车型零件总表11-25杨云飞ver','多工位车型零件总表20191122','二级缓存10.31','二级缓存拣货&停车位置1119','翻包装清单','排序内容明细(大类)1122','送料线路明细1122','线边拣货&停车位置','CPY零件信息总表20191121修复版','JIS大类清单(安吉)-完善线路与工位','JIS零件清单 11.25','JIS时间参数','LOC拣货位置-renew','M1至工段时间','suma拣货&停车位置','SUMA排序大类模数1122']
for i in range(len(n)):
names['data'+str(i)] = pd.read_csv(n[i]+'.csv')
2.2、时间处理函数
2.2.1、pd.to_datetime()
pd.read_csv()后有的时间数据会是Object数据类型,需要将其转换为时间类型,再做下一步的处理。
gdsj1 = data0.loc[:,['订单号','过点日期时间','车型','六位车型']]
gdsj1['time'] = pd.to_datetime(gdsj1['过点日期时间'])
可将数据框gdsj1中time列转化datetime64类型,每个数据都以时间戳(Timestamp)的形式存储。
2.2.2、timedelta()
在需要计算时间的加减时,需要用到timedelta()函数。
首先需要调用datetime包,并从中调用timedelta
import datetime
from datetime import timedelta
timedelta()函数可以指定时、分、秒、天等时间参数
timedelta(days=0, seconds=0, microseconds=0, milliseconds=0, minutes=0, hours=0, weeks=0)
可以利用timedelta()函数对时间戳(timestamp)进行运算
lhb1['理论消耗时间'] = [x + timedelta(hours = 1, minutes = 10) +timedelta(minutes = round((y-142)*60/64)) for x,y in zip(lhb1['过点日期时间'],lhb1['节拍'])]
2.2.3、dt.time(dt.year;dt.day;dt.hour)
有时候,只想取完整的时间中的一部分,比如只是时分秒,这是就用到dt.time
比如,现有一个数据框,time一列是以时间戳存储的数据,可以用dt.time截取需要的部分。
df
Out[101]:
time num
0 2019-11-21 12:13:01 3
1 2019-11-22 21:24:34 4
df['time'].dt.hour
Out[102]:
0 12
1 21
Name: time, dtype: int64
df['time'].dt.time
Out[103]:
0 12:13:01
1 21:24:34
Name: time, dtype: object
df['time'].dt.year
Out[104]:
0 2019
1 2019
Name: time, dtype: int64
df['time'].dt.day
Out[105]:
0 21
1 22
Name: time, dtype: int64
2.3、zip()
在使用列表生成器时,需要对数据框中的多个字段进行循环操作,这时就需要使用zip()函数。
sumakw = [np.nan if pd.isna(y) and z == '二级缓存' else x for x, y, z in zip(lh25['SUMA库位'],lh25['SUMA库位_不需要'],lh25['备注'])]
2.4、去重和排序
2.4.1、去重drop_duplicates()
在处理数据的过程中,很多时候需要对数据去重,这时可以使用drop_duplicates()函数
参数:
DataFrame.drop_duplicates(subset=None, keep='first', inplace=False)
1.subset 用来指定数据框里的哪一列,默认是所有的列;
2.keep 是选择去重之后是否保留重复项,或者保留重复项的哪一个。可选 {‘first’, ‘last’, False},分别是保留重复项的第一个,保留重复项的最后一个和不保留重复项,默认值是 ‘first’ ;
3.inplace 是选择直接在原来数据上修改还是保留一个副本
2.4.2、排序sort.values()
pandas中的sort_values()函数,可以将数据集依照某个字段中的数据进行排序,该函数即可根据指定列数据也可根据指定行的数据排序。
参数:
DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind=‘quicksort’, na_position=‘last’)
axis: 默认值是 0,即纵向排序,如果为1,则是横向排序
by:如果axis=0,那么by=“列名”;如果axis=1,那么by=“行名”;
ascending:True则升序,如果是多个字段排序可以是[True,False],即第一字段升序,第二个字段降序
如:
lhb11 = lhb11.sort_values(['理论拉动时间','排序单'],ascending = [True,True])
inplace:是否用排序后的数据替换现有的数据
kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, 默认是‘quicksort’。
na_position:{‘first’, ‘last’}, 默认是 ‘last’,即将缺失值排在最后面
2.5、表联合merge()
参数:
merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
left、right分别是左右数据框;
how指定了联合方式,左联合,右联合,内联合和外联合;
left_on,right_on分别是联合是左表的字段名,和右表的字段名
on指定两表的联合字段(字段名相同时使用)
详情见以下链接:
https://blog.csdn.net/qq_21840201/article/details/80727504
2.5、np.nan
在处理数据时,需要将某些值设为nan,需要用到np.nan
lhb1['主库位编组组合'] = [x+'_'+y if pd.notna(y) else np.nan for x,y in zip(lhb1['线路'],lhb1['主库位拣货位置'])]
2.6、pd.isna()和pd.notna()
判断某个值是nan或者不是nan,可以使用pd.isna()和pd.notna()函数。
3、踩坑和心得
3.1 关于循环
使用python处理数据,可以直接对元素进行循环,而不是通过索引循环,通过索引循环会太慢了。
3.2 关于切片
在对数据框进行切片时,如果一个列需要满足多个条件,需要使用&或者|,而不是使用and或者or,同时每个条件需要加个括号。
hb1 = lhb1.loc[lhb1['理论发货时间']>time1[0] and lhb1['理论发货时间']<time1[1],:]
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
需改为
lhb1 = lhb1.loc[(lhb1['理论发货时间']>time1[0]) & (lhb1['理论发货时间']<time1[1]),:]