Python数据清洗处理,csv,pandas,数据匹配

写在前面

本人python新手一枚,最近毕业论文需要用python处理数据,大概就是两年前学过一些python基础,最近重新把python捡起来了,由于这个数据处理过程对我这种新手来说过于艰难,所以想要把它记录下来,方便以后需要的时候再回顾,也希望其他同学遇到类似问题的时候可以更快找到解决方法~

下面正文开始

1. 要用到的库

import os
import pandas as pd
import openpyxl
import csv
import xlrd

2. 遍历文件夹,获取文件夹下的文件路径

#遍历某个文件夹下的所有文件,并将其路径存储到列表里
#这里只遍历了两层,如果有更多层文件夹的话可以继续往下遍历
def get_files():
    l = []
    directory = '文件夹路径'
    for f in os.listdir(directory):
        file_path = os.path.join(directory,f) #第一层
        for folder in os.listdir(file_path):
            files = os.path.join(file_path, folder) #第二层    
        l.append(files)
    return l
path = get_files()

3. 文件合并

如果上面文件夹里的文件是xlsx文件,则直接使用pd.read_excel()函数。
如果是xls文件,则使用pd.read_excel(文件路径,engine=‘xlrd’, index_col=False)

for i in path:
    df = pd.read_csv(i,index_col=False)
    df = df.loc[:, ['区域','板块','租金', '被叫手机号', '被叫姓名','被叫时长(秒)', '拨打时间']] #这里定义的是选取该文件的哪些列,全部都保留的话可以省略这条
    df.to_csv('文件路径.csv',mode='a',index=False) #这里的'a'是追加的意思,方便合并
    print(i)

4. 数据清洗

#去除重复数据
df2 = pd.read_csv('文件路径',index_col=False)
df2.drop_duplicates(inplace=True)
print('finish part2')

#把以下列的所有空值赋值为null后,删除含有null的行
df2['被叫手机号'] = df2['被叫手机号'].fillna('null')
df2 = df2[~df2['被叫手机号'].isin(['null'])]#该方法也可以用来删除包含特定字段的行
df2.to_csv('文件路径',mode='w',index=False) #做完去重和缺失值处理后写入文件
print('finish part3')

5. 遍历csv文件的每一行

因为我的数据需要,pandas里面我不知道怎么去遍历每一行,所以我用了csv这个包,如果某一行的数据不符合要求就删掉,把符合要求的写进一个新的csv里面

import csv
l = []
f = open('文件路径','r',encoding='utf-8')
reader = csv.reader(f)
f1 = open('文件路径','w+',encoding='utf-8',newline='')
writer = csv.writer(f1)
header = ['区域','板块','租金', '被叫手机号', '被叫姓名','被叫时长(秒)', '拨打时间']
writer.writerow(header)
#下面是判断手机号是不是以1开头,长度为11位,如果不是就删掉
#名字里有没有测试这两个字,如果有也删掉
for line in reader:
    if line[4][0] != '1':
        #print(line[2])
        continue
    if len(line[4]) != 11:
        #print(line[2])
        continue
    if '测试' in line[5]:
        continue
    else:
        writer.writerow(line)
print('finish')
f.close()
f1.close()

数据清洗阶段基本上就完成了,如果还有其他需求的小伙伴也可以根据上面的内容自行修改。

接下来就是进行一些数据的计算、分组统计和匹配等等,这里仅列出比较通用的部分。

6. 数据计算和匹配

- 分组统计

如果你的数据里同一个id或者同一个时间有多个值,那么就可以用pandas里的groupby函数进行分组计数、求和、求平均值等等。groupby用法很多,可自行百度。

df = pd.read_csv('文件路径',index_col=False)
g = df.groupby(['id','月份'])['被叫次数'].sum().reset_index()#这里是求每个人每个月一个被呼叫了多少次,用的是sum函数。
g.to_csv('文件路径',mode='w',index=False)

如果需要计数的话需要用count()或size()函数,这两个函数的区别是count()只计算有值的数,size则是就算该行有缺失值也会计算进去。

- 数据匹配

当有两个或多个表格,它们中包含同一个唯一字段(即数据库里的主码)需要根据该字段进行匹配时,可以用pandas的merge函数。

left = pd.read_csv('文件路径',index_col=False)
right = pd.read_csv('文件路径',index_col=False)
#right = right.loc[:,['id','房东电话','月份']] 可以只选取其中部分字段
result = pd.merge(left,right,left_on=['注册时间','时间'],right_on=['注册时间','时间'],how="left") #merge用法自行百度, on参数和how参数很重要
result.to_csv('文件路径',mode='w',index=False)
print('finish!')

- 计算两个时间之间的间隔天数

这个是参考某位大佬的,具体出处戳这里

import time

def demo(day1, day2):
    time_array1 = time.strptime(day1, "%Y/%m/%d")#如果分隔符不一样改掉即可
    timestamp_day1 = int(time.mktime(time_array1))
    time_array2 = time.strptime(day2, "%Y/%m/%d")
    timestamp_day2 = int(time.mktime(time_array2))
    result = (timestamp_day2 - timestamp_day1) // 60 // 60 // 24
    return result

- 生成虚拟变量

df = pd.read_csv('文件路径',index_col=False)
renttype_dummy = pd.get_dummies(df['租赁类型'])
df = df.join(renttype_dummy)
df.to_csv('文件路径',mode='w',index=False)

- 判断某个房子在某月是否处于上架状态

(在上架日期和下架日期之间)
这其实是一个非常笨的办法,但我也想不到其他的了…
逻辑就是把上架日期和下架日期的年份和月份取出来合并到一起,即201701这种形式,然后比较大小即可。
例如201709 < 201710 <201801,那这个房子在201710的时候肯定是处于上架状态的。

#计算房东每月总房源数量
f = open('文件路径','r',encoding='utf-8')
reader = csv.reader(f)
f1 = open('文件路径','w',encoding='utf-8')
writer = csv.writer(f1)
header = ['id','月份']
writer.writerow(header)
for line in reader:
    xiajia = line[-6].split('/')#用分隔符把年月日分开
    print(xiajia)
    shangjia = line[-5].split('/')#用分隔符把年月日分开
    if len(xiajia[1]) == 1:
        month1 = '0' + xiajia[1]#以/为分隔符的日期一般月份都是不带0的
        xjdate = xiajia[0] + month1
    else:
        xjdate = xiajia[0] + xiajia[1]
    if len(shangjia[1]) == 1:
        month2 = '0' + shangjia[1]
        sjdate = shangjia[0] + month2
        #print(sjdate)
    else:
        sjdate = shangjia[0] + shangjia[1]
        #print(sjdate)
#下面就是判断它属于哪个月,有可能同时属于好几个月
    if int(sjdate) <= 201701 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201701')
        writer.writerow(l)
    if int(sjdate) <= 201702 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201702')
        writer.writerow(l)
    if int(sjdate) <= 201703 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201703')
        writer.writerow(l)
    if int(sjdate) <= 201704 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201704')
        writer.writerow(l)
    if int(sjdate) <= 201705 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201705')
        writer.writerow(l)
    if int(sjdate) <= 201706 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201706')
        writer.writerow(l)
    if int(sjdate) <= 201707 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201707')
        writer.writerow(l)
    if int(sjdate) <= 201708 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201708')
        writer.writerow(l)
    if int(sjdate) <= 201709 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201709')
        writer.writerow(l)
    if int(sjdate) <= 201710 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201710')
        writer.writerow(l)
    if int(sjdate) <= 201711 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201711')
        writer.writerow(l)
    if int(sjdate) <= 201712 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201712')
        writer.writerow(l)
    if int(sjdate) <= 201801 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201801')
        writer.writerow(l)
    if int(sjdate) <= 201802 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201802')
        writer.writerow(l)
    if int(sjdate) <= 201803 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201803')
        writer.writerow(l)
    if int(sjdate) <= 201804 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201804')
        writer.writerow(l)
    if int(sjdate) <= 201805 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201805')
        writer.writerow(l)
    if int(sjdate) <= 201806 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201806')
        writer.writerow(l)
    if int(sjdate) <= 201807 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201807')
        writer.writerow(l)
    if int(sjdate) <= 201808 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201808')
        writer.writerow(l)
    if int(sjdate) <= 201809 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201809')
        writer.writerow(l)
    if int(sjdate) <= 201810 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201810')
        writer.writerow(l)
    if int(sjdate) <= 201811 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201811')
        writer.writerow(l)
    if int(sjdate) <= 201812 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201812')
        writer.writerow(l)
    if int(sjdate) <= 201901 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201901')
        writer.writerow(l)
    if int(sjdate) <= 201902 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201902')
        writer.writerow(l)
    if int(sjdate) <= 201903 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201903')
        writer.writerow(l)
    if int(sjdate) <= 201904 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201904')
        writer.writerow(l)
    if int(sjdate) <= 201905 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201905')
        writer.writerow(l)
    if int(sjdate) <= 201906 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201906')
        writer.writerow(l)
    if int(sjdate) <= 201907 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201907')
        writer.writerow(l)
    if int(sjdate) <= 201908 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201908')
        writer.writerow(l)
    if int(sjdate) <= 201909 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201909')
        writer.writerow(l)
    if int(sjdate) <= 201910 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201910')
        writer.writerow(l)
    if int(sjdate) <= 201911 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201911')
        writer.writerow(l)
    if int(sjdate) <= 201912 <= int(xjdate):
        l = []
        l.append(line[0])
        l.append(line[1])
        l.append('201912')
        writer.writerow(l)
f.close()
f1.close()

最最后,立个小小的flag,今年一定要更深入的学习python和sql,希望所有的数据人都能快乐(哭)。
如果有大佬有更好的方法,请多多指教。

你可能感兴趣的:(python,数据分析)