这里写目录标题
- 一,读入csv文件时,添加parse_dates参数,把时间转为时间戳
- 二,dataframe 新增加列,并用apply方法根据其他列的值计算
- 三,获取某一列的值 .values.tolist()
- 四,concat之后reset_index(drop=True)
- 五,按照某一列分组 groupby,得到的对象为迭代器,可以通过for获取,分组之后时间需要再次(之前转过一次)转为pandas中的时间对象类型,通过info()查看对象各列的数据类型
- 六,获取每个组的第一条数据以及索引,iloc,参数必须为整数
- 七,通过index获取某一列满足条件的对应的索引,index
- 八,删除某一列数据中重复的项,drop_duplicates
- 九,时间如何只提取到日(去掉后面时分秒).date
- 十,截取中间某一段满足条件的数据,并返回索引idxmax()和idxmin(),以及全部索引index
- 十一,Nan 填充
- 十二,读取已有的csv文件,并按照文件中的名称更新对应的数据
- pandas groupby之后的for循环加速
- 71803倍!超强Pandas循环提速攻略
- 加快循环操作和Numpy数组运算速度
- Jupyter能够打印所有交互式输出,而不仅仅是最后的结果
- 判断列表a中的数据是否在列表b中,并生成相应的标签
- 数据下载
- 根据时间间隔循环读取数据
- 按照电脑文件中文件的顺序读取文件
- 获取pandas中当前索引行的下一行(适用于索引不是序号的时候,以下案列中的索引为时间)
- pandas 画图
- pandas根据列排序
- python 统计list中各个元素出现的次数
- pandas 调换列的顺序
- pandas 带条件匹配
- dataframe 修改列名
- dataframe中的数据类型和相互转换
- dataframe日期转为星期几
- list嵌套列表转一维
- pandas groupby之后获取索引和值
- jupyter notebook使用技巧
- 如何根据多列的值将多行与python pandas 合并成一行?
- 时间加减报错`ufunc add cannot use operands with types dtype('
以下方法以此图为例
一,读入csv文件时,添加parse_dates参数,把时间转为时间戳
temp = pd.read_csv(file_path,parse_dates=['告警开始时间'])
二,dataframe 新增加列,并用apply方法根据其他列的值计算
temp['IS_VIP_Alarm'] = temp['告警名称'].apply(lambda x: 1 if x in VIP_Alarm else 0)
def Alarm_to_index(df):
index = word_to_id[df]
return index
df['Alarm_to_index'] = df['告警名称'].apply(Alarm_to_index)
三,获取某一列的值 .values.tolist()
val = temp['IS_VIP_Alarm'].values.tolist()
四,concat之后reset_index(drop=True)
dl = []
for i in tqdm(file_path_list):
file_path = os.path.join(data_path,i)
temp = pd.read_csv(file_path,parse_dates=['告警开始时间'])
temp['IS_VIP_Alarm'] = temp['告警名称'].apply(lambda x: 1 if x in VIP_Alarm else 0)
temp['基站编码'] = i
#剔除不包含重要报警的temp
val = temp['IS_VIP_Alarm'].values.tolist()
if 1 in val:
dl.append(temp)
df = pd.concat(dl)
df = df.reset_index(drop=True)
五,按照某一列分组 groupby,得到的对象为迭代器,可以通过for获取,分组之后时间需要再次(之前转过一次)转为pandas中的时间对象类型,通过info()查看对象各列的数据类型
data_group = df.groupby(['基站eNBID'],sort=False)#根据基站名称分组
for name,group in tqdm(data_group):
group['告警开始时间'] = pd.to_datetime(group['告警开始时间'])
group.info()
to_datetime之前
to_datetime之后
六,获取每个组的第一条数据以及索引,iloc,参数必须为整数
start_time = group.head(1).iloc[0,0]
start_index = group.head(1).index[0]
七,通过index获取某一列满足条件的对应的索引,index
new_group_alarm = group[group['IS_VIP_Alarm']>0]
alarm_index = new_group_alarm.index #报警时间对应的行号
八,删除某一列数据中重复的项,drop_duplicates
alarm_index = group[group['IS_VIP_Alarm']>0].drop_duplicates(subset = '告警开始时间').index
九,时间如何只提取到日(去掉后面时分秒).date
alarm_time_day = group.loc[i,'告警开始时间'].date()#2020-01-03
十,截取中间某一段满足条件的数据,并返回索引idxmax()和idxmin(),以及全部索引index
x = group.loc[(group['告警开始时间'] > a) & (alarm_time >= group['告警开始时间']), '告警开始时间']
if len(x)>0:
b = x.idxmin()
十一,Nan 填充
temp_2.fillna(value=0,inplace=True)
十二,读取已有的csv文件,并按照文件中的名称更新对应的数据
temp_2 = pd.read_csv('Sample31日.csv',encoding='gbk')
temp_2["未来24小时发生退服类告警的概率"] = temp_2['基站名称'].map(alarm_dict)
temp_2.to_csv('test/Sample31日.csv',mode='w',encoding='gbk',index=0)
pandas groupby之后的for循环加速
使用多线程加速
from joblib import Parallel, delayed
import multiprocessing
result=pd.DataFrame()
def fun_avg(uId,groupData):
temp2_dict=groupData.groupby('category')['times','duration'].mean().T.to_dict()
line={
}
line['uId']=uId
for cat in temp2_dict:
line[cat+'_duration']=temp2_dict[cat]['duration']
line[cat+'_times']=temp2_dict[cat]['times']
return pd.DataFrame(pd.Series(line)).T
def applyParallel(dfGrouped, func):
ret = Parallel(n_jobs=multiprocessing.cpu_count())(delayed(func)(name,group) for name, group in dfGrouped)
return pd.concat(ret)
result = applyParallel(pd_data.groupby('uId'), fun_avg)
71803倍!超强Pandas循环提速攻略
加快循环操作和Numpy数组运算速度
Jupyter能够打印所有交互式输出,而不仅仅是最后的结果
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
判断列表a中的数据是否在列表b中,并生成相应的标签
VIP_Alarm = ['网元连接中断','小区不可用告警']
for file in file_path_list:
temp = pd.read_csv(file)
Alarm_list = temp['告警名称'].values.tolist()
print(Alarm_list)#['X2接口故障告警', '网元连接中断', '[省内]4G基站状态异常', 'X2接口故障告警']
inter = [1 if i in VIP_Alarm else 0 for i in Alarm_list]
print(inter)# [0, 1, 0, 0]
数据下载
def download():
#通过python的requests类,下载存储在
#https://dataset.bj.bcebos.com/imdb%2FaclImdb_v1.tar.gz的文件
corpus_url = "https://dataset.bj.bcebos.com/imdb%2FaclImdb_v1.tar.gz"
web_request = requests.get(corpus_url)
corpus = web_request.content
#将下载的文件写在当前目录的aclImdb_v1.tar.gz文件内
with open("./aclImdb_v1.tar.gz", "wb") as f:
f.write(corpus)
f.close()
download()
3 pandas concat之后 记得用reset_index去处理index(把index重新按照0开始排序)
dl = []
for file in file_path_list:
xxxxx#省略中间代码
dl.append(temp)
df = pd.concat(dl)
df = df.reset_index(drop=True)
4 list不能和str相+操作,如果需要 可以用join方法
path3 = ""
if 1 not in df_period['IS_VIP_Alarm'].values.tolist():
c.write(path3.join(df_period_pre['告警名称'].values.tolist())+' '+str(0)+'\n')
根据时间间隔循环读取数据
df['告警开始时间'] = pd.to_datetime(df['告警开始时间'])
df.index = df['告警开始时间']
data_group = df.groupby(['基站eNBID'],sort=False)#根据基站名称分组
#访问每一组的组名和每组的内容
for name,group in data_group:
start_time = group['告警开始时间'][0].date()#通过data可以去年时分秒数据
while start_time < (group['告警开始时间'][-1].date() - datetime.timedelta(days=5)):
end_time = start_time + datetime.timedelta(days=7)
#获取前7天的数据
df_period_pre = group[start_time: end_time]
#获取第八天的数据
df_period = group[end_time: (end_time+datetime.timedelta(days=1))]
path3 = ""
Alarm_list = df_period['IS_VIP_Alarm'].values.tolist()
if not df_period_pre.empty:
if 1 in Alarm_list:
c.write(path3.join(df_period_pre['告警名称'].values.tolist())+' '+str(1)+'\n')
else:
c.write(path3.join(df_period_pre['告警名称'].values.tolist())+' '+str(0)+'\n')
start_time += datetime.timedelta(days=1)
按照电脑文件中文件的顺序读取文件
file_path_list = os.listdir(data_path)
#按照文件名称中的数字排名
file_path_list.sort(key=lambda x:int(x.split('_')[-1].split('.')[0]))
获取pandas中当前索引行的下一行(适用于索引不是序号的时候,以下案列中的索引为时间)
get_loc(i)有可能返回slice对象,不能和整数直接相加,所以加判断**
index = new_group.index.get_loc(i)
if isinstance(index, slice):
next_index = index.stop+1
else:
next_index = index+1
#获取重要报警下一条的报警时间
next_time = new_group.index[next_index]
pandas 画图
plt.title('Epic Chart')
plt.ylabel('Y axis')
plt.xlabel('X axis')
plt.show()
Series.plot() 和 Dataframe.plot()
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from pandas import Series
# 创建一个随机种子, 把生成的值固定下来
np.random.seed(666)
s1 = Series(np.random.randn(1000)).cumsum()
s2 = Series(np.random.randn(1000)).cumsum()
# series 中 也包含了 plot 方法
s1.plot(kind = 'line', grid = True, label = 'S1', title = 'xxx')
s2.plot(label = 's2')
plt.legend()
plt.show()
# 通过 子图的 方式,可视化 series
figure, ax = plt.subplots(2, 1)
ax[0].plot(s1)
ax[1].plot(s2)
plt.legend()
plt.show()
# 通过 series中的plot方法进行指定是哪一个子图
fig, ax = plt.subplots(2, 1)
s1.plot(ax = ax[1], label = 's1')
s2.plot(ax = ax[0], label = 's2')
plt.legend()
plt.show()
# Dataframe 也有个内置方法 plot
df.plot(kind = 'bar') # kind = 'bar'
plt.show()
# 横向的柱状图
df.plot(kind = 'barh') # kind = 'barh' 可以是一个横向的柱状图
plt.show()
# 将每个column的柱状图堆叠起来
df.plot(kind = 'bar', stacked = True)
plt.show()
# 填充的图
df.plot(kind = 'area')
plt.show()
# 可以进行选择
b = df.iloc[6] # 这时候的b是一个series
b.plot() # 可以看出x轴就是colume的name
plt.show()
# 可以将所有的行全部画在一张图里
for i in df.index:
df.iloc[i].plot(label = str(i))
plt.legend()
plt.show()
# 对一列进行画图
df['A'].plot()
plt.show()
# 多列画图,同上
# 注意:默认是按照column来进行画图的,
# 如果需要按照 index 画图,可以将 dataframe 转置一下
df.T.plot()
plt.show()
df2 = df.groupby(["Category", "Result"]).size().reset_index(name='Count')
df3 = pd.pivot_table(df2, values='Count', columns=['Result'], index = "Category",
aggfunc=np.sum, fill_value=0)
df4 = pd.pivot_table(df2, values='Count', columns=['Category'], index = "Result",
aggfunc=np.sum, fill_value=0)
fig, ax = plt.subplots(1,2, figsize=(10,4))
df3.plot(kind="bar", ax=ax[0])
df4.plot(kind="bar", ax=ax[1])
plt.show()
pandas根据列排序
pandas排序的方法有很多,sort_values表示根据某一列排序
pd.sort_values("xxx",inplace=True)
python 统计list中各个元素出现的次数
from collections import Counter
a = [1, 2, 3, 1, 1, 2]
result = Counter(a)
print result
pandas 调换列的顺序
一:获取DataFrame列标签
cols = list(dataframe)
二:改变列标签为指定顺序
cols.insert(0,cols.pop(cols.index(‘c’)))
insert方法:
1.功能
insert()函数用于将指定对象插入列表的指定位置。
2.语法
list.insert(index, obj)
3.参数
index: 对象obj需要插入的索引位置。
obj: 插入列表中的对象。
pandas 带条件匹配
具体可以参考下面这个方式
d1['name'] = np.where(d1['school'].apply(lambda y: any(re.search(x,y) for x in d2['abb'].apply(lambda x:'.*'.join(list(x))))),'YES','NO')
pandas merge操作
merge()函数的具体参数
用法:
DataFrame1.merge(DataFrame2, how=‘inner’, on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=(’_x’, ‘_y’))
参数说明
参数 | 说明 |
---|---|
how | 默认为inner,可设为inner/outer/left/right |
on | 根据某个字段进行连接,必须存在于两个DateFrame中(若未同时存在,则需要分别使用left_on和right_on来设置) |
left_on | 左连接,以DataFrame1中用作连接键的列 |
right_on | 右连接,以DataFrame2中用作连接键的列 |
left_index | 将DataFrame1行索引用作连接键 |
right_index | 将DataFrame2行索引用作连接键 |
sort | 根据连接键对合并后的数据进行排列,默认为True |
suffixes | 对两个数据集中出现的重复列,新数据集中加上后缀_x,_y进行区别 |
dataframe 修改列名
a.rename(columns={
'A':'a', 'B':'b', 'C':'c'}, inplace = True)
dataframe中的数据类型和相互转换
df['col2'] = df['col2'].astype('int')
pd.to_XXX()方法
to_numeric() #转化为数字型,根据情况转化为int或float
to_string() #转化为字符型
to_dict() #转化为字典,不能处理单列数据
to_timestamp() #转化为时间戳,以前还特意写了个函数转换,何必呢
to_datetime() #转化为datetime64[ns]
dataframe日期转为星期几
temp1['星期几'] = temp1.groupby(['告警日期'])['告警开始时间'].transform(lambda x:x.dt.day_name())
list嵌套列表转一维
import itertools
a = [[1,2,3],[4,5,6], [7], [8,9]]
out = list(itertools.chain.from_iterable(a))
pandas groupby之后获取索引和值
#得到分组后ID(行名称)对应的数量
id_name = df_gp.size().values
#得到分组后的ID(行名称)
id_num = df_gp.size().index
jupyter notebook使用技巧
如何根据多列的值将多行与python pandas 合并成一行?
时间加减报错ufunc add cannot use operands with types dtype('<M8[ns]') and dtype('O')
解决
报错代码
group[group['告警日期'] == (start_date + datetime.timedelta(days=7))]
原因 不知道
type(datetime.timedelta(days=7)),type(start_date)
#(datetime.timedelta, numpy.datetime64)
修改如下,没有报错了
group[group['告警日期'] == (pd.to_datetime(start_date) + datetime.timedelta(days=7))]
其实start_date在之前已经用pd.to_datetime转过一次了,但是在进行和timedelta加减操作的时候还要再转一次,记住就行了,时刻转,应该没错。
dataframe增加list为一行
df = pd.DataFrame(columns=list("ABC"))
df.loc[len(df)] = [1,2,3]
numpy.datetime64( ) 时间和 datetime.datetime 互转
Python的repr函数
repr() 函数将对象转化为供解释器读取的形式。
a="123"
print(a)
结果:123
正常情况下打印a是经过了pycharm优化处理过的,看不到两端的 " "
所以:
a="123"
print(repr(a))
结果:'123'
列表判断相等,必须先排序(顺序不同,判定不相等)
#方法一
list1.sort() == list2.sort() # 改变list本身
#方法二
sorted(list1) == sorted(list2) # 不改变list本身
找出list中某一元素并返回所有匹配index值
alarm = group['Alarm_to_index'].values.tolist()
if len(set(alarm)&set([7,39]))>0:
#返回list中7和39元素的索引
test_alarm_index = [i for i,x in enumerate(alarm) if x == 7 or x == 39 ]
tr = alarm[(test_alarm_index[-1]+1):]
字典的持久化保存和load
后面的pickle.HIGHEST_PROTOCOL参数不能省略,否则加载会报错,这个报错尝试了网上的大部分方法不管用
报错EOFError Ran out of input这里是引用
with open('feature.pkl', 'wb') as f:
pickle.dump(image_dict, f, pickle.HIGHEST_PROTOCOL)
load
with open('feature.pkl', 'rb') as f:
images_dict = pickle.load(f)
print("image_num:{}".format(len(images_dict)))
字典的动态删除
字典存储的信息在处理的时候,经常会根据判断条件,动态的修改,字典本身是不可以动态修改的,否则循环中断,会报错,必须先转为list
i = 0
#for key in images_dict:#这样后面del就会直接报错
for key in list(images_dict.keys()):#先转为列表
if len(images_dict[key]) > 2:
img_save = images_dict[key][0]
img_name = images_dict[key][1]
img_unrec_path = os.path.join(output_folder,img_name)
print(img_unrec_path)
cv2.imwrite(img_unrec_path,img_save)
del images_dict[key]
i+=1
关于OpenCV的人脸识别和dlib人脸识别的对比
由于项目需要,针对项目中的1800多张图片识别人脸
OpenCV的级联识别人脸方式 有110张没有识别到,把没有识别到的拿出来再次传进函数依然没有识别出来,暂不清楚为什么(图片整理质量很高,不存在模糊失真等),另外OpenCV识别的人脸范围较大
用dlib人脸识别,有11张没有识别出来,效果还是不错的,识别的人脸精准。
最后为了方便后续的特征比对,统一用dlib提取
#dlib方式
detector = dlib.get_frontal_face_detector()
# 检测人脸
dets = detector(gray,0) # 1代表放大图像一倍再检查
# 遍历所有的人脸
if dets:
face = dets[0]#我处理的图片只有一个人脸,有多张人脸的话 要循环
y1 = face.top() if face.top() > 0 else 0
y2 = face.bottom() if face.bottom() > 0 else 0
x1 = face.left() if face.left() > 0 else 0
x2 = face.right() if face.right() > 0 else 0
corp = img[y1:y2, x1:x2]
size_224 = cv2.resize(corp,(224,224))
cv2.imwrite(os.path.join(output_folder, name), size_224)
else:
cv2.imwrite(os.path.join(output_folder, name),img)
#OpenCV方式
face_cascade = cv2.CascadeClassifier('opencv/haarcascades/haarcascade_frontalface_default.xml')
# 检测人脸
boxes = face_cascade.detectMultiScale(gray, 1.3, 5)
# 遍历所有的人脸
if len(boxes) == 1:
x, y, w, h = boxes[0]
corp = img[y:y + h, x:x + w]
size_224 = cv2.resize(corp,(224,224))
cv2.imwrite(os.path.join(output_folder, name), size_224)
else:
cv2.imwrite(os.path.join(output_folder, name),img)
换行写入TXT文件
file_path_list = glob.glob(os.path.join(output_folder, "*.jpg"))# 返回指定路劲下所有jpg格式文件的路径
with open('list.txt','w') as fa: #设置文件对象
for index,f in enumerate(file_path_list):
print("正在处理第{0}张".format(index))
name = os.path.basename(f)
name += "\n"
fa.writelines(name)