pandas及python代码

这里写目录标题

以下方法以此图为例
在这里插入图片描述

一,读入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之前
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)    

猜你喜欢

转载自blog.csdn.net/weixin_44831720/article/details/106714740
今日推荐