前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python数据分析实战之技巧总结

Python数据分析实战之技巧总结

作者头像
DataCharm
发布2021-02-22 15:03:58
2.4K0
发布2021-02-22 15:03:58
举报
文章被收录于专栏:数据 学术 商业 新闻

数据分析实战中遇到的几个问题?

—— Pandas的DataFrame如何固定字段排序

—— 保证字段唯一性应如何处理

—— 透视表pivot_table函数转化长表注意问题

——Pandas的DataFrame数据框存在缺失值NaN运算如何应对

——如何对数据框进行任意行列增、删、改、查操作

—— 如何实现字段自定义打标签

Q1:Pandas的DataFrame如何固定字段排序

代码语言:javascript
复制
df_1 = pd.DataFrame({"itemtype": list(df.ITEMTYPE.unique())})
#固定字段顺序
list_custom = ["电耗量", "照明插座用电", "空调用电", "动力用电", "特殊用电"]

switch = {"电耗量": lambda x: list(x[x.ITEMTYPE == "电耗量"]["BRANCHID"]),
          "照明插座用电": lambda x: list(x[x.ITEMTYPE == "照明插座用电"]["BRANCHID"]),
          "空调用电": lambda x: list(x[x.ITEMTYPE == "空调用电"]["BRANCHID"]),
          "动力用电": lambda x: list(x[x.ITEMTYPE == "动力用电"]["BRANCHID"]),
          "特殊用电": lambda x: list(x[x.ITEMTYPE == "特殊用电"]["BRANCHID"])}

fxzl_list = []
fxmc_list = []
#列表生成式截留,其它方法参见推文

Q2:注意保证字段唯一性,如何处理

代码语言:javascript
复制
#以名称作为筛选字段时,可能出现重复的情况,实际中尽量以字段id唯一码与名称建立映射键值对,作图的时候尤其注意,避免不必要的错误,可以做以下处理:
1、处理数据以id为字段,最后统计用建立的key-value映射
X.index = X.index.map(_dict)
X1=X1.rename(columns=_dict)
2、加上区分字段
 p1=list(X1.columns)
 X2.columns=[p1[i]+"-"+str(i) for i in range(len(p1))]

当然也可以对图例标签进行自定义设置区分,具体参见推文Python图表自定义设置

Q3:透视表pivot_table函数转化长表注意问题

代码语言:javascript
复制
import pandas as pd
import numpy as np
#构建重塑时间序列
index=pd.DataFrame({"时间":pd.date_range(start="2019/1/1",end="2019/12/31",freq="d")})
#重塑对象清单
df_list=list(df.分项名称.unique())

# 构建空表,存储处理的对象
df_empty=pd.DataFrame(columns=["时间","分项名称","用电量"])
for j in range(len(df_list2)):
    df_1=df[df.分项名称==df_list2[j]]
#     df_1=df_1.drop_duplicates(subset=["时间"])
    DATA=pd.merge(index,df_1,how="left",on="时间")
    DATA["分项名称"]=DATA["分项名称"].fillna(df_list[j])
    df_empty=df_empty.append(DATA,ignore_index=True)#输出处理后的结果

#长表转为宽表,存在缺失值,不能保证时间序列的完整性
df2=df_empty.pivot_table(index=["时间"],columns="分项名称",values="用电量").round(decimals=2).reset_index()

#可以如下处理,保证时间序列完整,此处固定显示顺序,参见问题一
L_TYPE_day=list(df_empty.分项名称.unique())
df2=pd.DataFrame(index)
for i in range(len(L_TYPE_day)):
    df_empty_day=df_empty[df_empty.分项名称==L_TYPE_day[i]]
    df2[L_TYPE_day[i]]=list(df_empty_day["用电量"])

存在NaN值如何保证完整序列,数据结构如下

Q4、数据运算存在NaN如何应对

需求:pandas处理多列相减,实际某些元素本身为空值,如何碰到一个单元格元素为空就忽略了不计算,一般怎么解决!

代码语言:javascript
复制
#构造问题数据源
import pandas as pd
import numpy as np
from collections import Counter
a = Counter(A=1, B=2,C=1,D=2,E=1)

b=["1月","1月","2月","1月","1月","2月","1月"]

c1 =[70,80,40,50,60,90,70]
c2 =[30,40,20,15,30,30,40]
c3 =[20,20,10,20,10,20,10]
c4 =[10,10,5,10,np.nan,20,np.nan]
c5 =[10,5,5,np.nan,10,20,15]

df=pd.DataFrame({"建筑名称":list(a.elements()),"月份":b,"电耗量":c1,"照明用电":c2,"空调用电":c3,"动力用电":c4,"特殊用电":c5})
display(df)
代码语言:javascript
复制
代码语言:javascript
复制
#如果这样操作,发现所求列为空值,不是我想要的结果
df["照明用电"]=df["电耗量"]-df["空调用电"]-df["动力用电"]-df["特殊用电"]

应该如何处理?

代码语言:javascript
复制
#将dataframe数据转化为二维数组,这时候我们可以利用强大的np模块进行数值计算啦!
arr = df[[i for i in list(df.columns[2:]) if i in(["动力用电", "特殊用电", "空调用电"]) ]].values

df["分项之和"] = np.nansum(arr, axis=1)  

df["照明用电"] = df.apply(lambda x: x["电耗量"] - x["分项之和"], axis=1)

df.drop(columns=["分项之和"])
代码语言:javascript
复制

Q5、如何对数据框进行任意行列增、删、改、查操作

代码语言:javascript
复制
df1=df.copy()  #复制一下
# 增操作
#普通索引,直接传入行或列
# 在第0行添加新行
df1.loc[0] = ["F","1月",100,50,30,10,10] 
# 在第0列处添加新列
df1.insert(0, '建筑编码',[1,2,2,3,4,4,5]) 

df1.loc[:,"new"] = np.arange(7) 
df1["new1"]=np.arange(7)
# 在末尾添加列
#或利用字典赋值操作
_dict={"A":1,"B":2,"C":3,"D":4,"E":5,"F":6}
df1["建筑编码1"]=df1["建筑名称"].map(_dict)
#建立字典from collections import defaultdict
#一个个添加,dict_1=defaultdict(lambda:"N/A"),key不存在时,返回一个默认值dict_1[7]="G"
#以列表形式存放元组中,用dict()转换
test_dict=([8,"H"],[9,"I"])
dict_1=dict(test_dict)
#键值对
dict_1=df1.drop_duplicates(['建筑编码']).set_index("建筑编码")["建筑名称"]
#字典的keys()、values()、items()方法
# keys()用来获取字典内的所有键
#values()用来获取字典内所有值
#items()用来得到一组组键值对

# df1.append(df2) # 往末尾添加dataframe
# pd.concat([df1, df2, df3]) # 往末尾添加多个dataframe
# pd.concat([df1, df2, df3], axis = 1) # 往末尾添加多个dataframe

# # 按照关键字合并
# result = pd.merge(df1, df2, on='cities')
# result2 = pd.merge(df1, df2, on='cities', how='outer') 
df1
代码语言:javascript
复制
# 删
df3=df1.copy()
del df3['new1'] # 删除列
df3=df3.drop(['new', '建筑编码1'], axis = 1)  # 删除多列

df3=df3.drop([8, 9, 10])  # 删除多列

df3=df3.dropna() # 删除带有Nan的行

df3=df3.dropna(axis = 1, how = 'all') # 删除全为Nan的列

df3=df3.dropna(axis = 1, how = 'any') # 删除带有Nan的列

df3=df3.dropna(axis = 0, how = 'all') # 删除全为Nan的行

df3=df3.dropna(axis = 0, how = 'any') # 删除带有Nan的行 默认选项为此
代码语言:javascript
复制
# 改
df4=df1.copy()
df4
#切片索引,传入行或列的位置区间
df4.iloc[:,5]= np.arange(7)

# # 元素赋值修改
df4.loc[0, '电耗量'] = 900

df4.iloc[0, 2] = "3月"

# df.set_index("建筑名称")
#改列明和索引名
df4 =df4.rename(columns={"照明用电":"照明插座用电"},index={1:8})

df4.fillna(value = 1) # 用1填充缺失值


# 列赋值

df4['year'] = 2020

val = pd.Series(["type7","type2","type2","type3","type4","type4","type5"]) 

df4['建筑类型'] =val   #注意索引不能修改,否则修改行会缺失

# df4['建筑类型'] = ["type7","type2","type2","type3","type4","type4","type5"]  
代码语言:javascript
复制
# 查
df5=df1.copy()
df5.index # RangeIndex
df5.columns # Index
df5.values # ndarray

# 元素查找
df5_1= df5.loc[0,'建筑名称'] # 数据是什么类型,xx就是什么类型
# df5_1 = df5.loc[[0],['建筑名称']] # DataFrame类型
# # 行查找 
# df5_2 =df5.loc[0:2] # DataFrame类型012共3行
# df5_2=df5.iloc[0:2] # DataFrame类型 01共1行
df5_2= df5[0:3] # DataFrame类型 前三行

# 列查找
df5_3= df5.loc[:, '建筑编码'] # Series 列查找
df5_3 = df5.loc[:, ['建筑编码', '建筑名称']] # DataFrame类型 多列查找
df5_3 =df5.iloc[:, 0:2] # DataFrame类型 01列

df5_4= df5['建筑名称'] # Series类型

df5_4= df5.建筑名称 # Series类型 同上

df5_5 = df5[['建筑编码1', '建筑名称']] # DataFrame类型 按照新列序

df5_6= df5.filter(regex = '建筑编码1|建筑名称') # DataFrame类型 按照原列序

df5_7=df5[df5.电耗量 > 80]# 选择df5.电耗量中>80的行

# df5[df5.建筑名称.isin(['B', 'C'])] #DataFrame 条件查找

# df5[['建筑编码1', '建筑名称']][0:3] # DataFrame类型 

# # 块查找

df5_8= df5.iloc[0:2, 0:2] # DataFrame类型


#条件查找
# # 条件查找

df5_9=df5.动力用电.notnull() # Series类型 true与false的一列

# df5_9 df5['动力用电'].notnull() # Series 同上

df5_10= df5[df5.动力用电.notnull()] # DataFrame类型 按照year非空选择之后的结果

df5_11= df5[df5.动力用电.notnull()].values # ndarray类型 

df5_12= df5[df5.建筑名称== "D"][df5.月份 == '1月'] # DataFrame

#pandas库中使用.where()函数
# df5_13=df5.where((df5.月份=="1月")&(df5.动力用电>5)).dropna(axis=0)
# 或pandas库中的query()函数
df=df[df.建筑名称=="D"].query(("电耗量>60"))
#使用Numpy的内置where()函数,np.where(condition, value if condition is true, value if condition is false)
df['是否>30'] = np.where(df['照明用电']> 30, True, False)
# 再将样本筛选出
df= df[df['照明用电'] == True]
Q6:如何对字段打标签
#一般情况下,根据值大小,将样本数据划分出不同的等级
方法一:使用一个名为np.select()的函数,给它提供两个参数:一个条件,另一个对应的等级列表。
conditions = [
    (df['负载率'] <=0.3),
    (df['负载率'] > 0.3) & (df['负载率'] <= 0.5),
    (df['负载率'] > 0.5) & (df['负载率'] <= 0.75),
    (df['负载率'] <1)]
values = ['(0-0.3]', '(0.3-0.5]', '(0.5-0.75]', '(0.75-1]']
df['标签'] = np.select(conditions, values)
#统计支路NAME的标签处于(0.75-1]区间情况
df[(df['标签'] == '(0.75-1]')['NAME'].value_counts(normalize=True)

方法二:
bins=[0,0.3,0.5,0.75,1]
df["标签"]=pd.cut(df["负载率"],bins)

方法三:自定义打标签,参加推文
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-08-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DataCharm 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • —— Pandas的DataFrame如何固定字段排序
  • —— 保证字段唯一性应如何处理
  • —— 透视表pivot_table函数转化长表注意问题
  • ——Pandas的DataFrame数据框存在缺失值NaN运算如何应对
  • ——如何对数据框进行任意行列增、删、改、查操作
  • —— 如何实现字段自定义打标签
    • Q1:Pandas的DataFrame如何固定字段排序
      • Q2:注意保证字段唯一性,如何处理
        • 当然也可以对图例标签进行自定义设置区分,具体参见推文Python图表自定义设置
          • Q3:透视表pivot_table函数转化长表注意问题
          • 存在NaN值如何保证完整序列,数据结构如下
            • Q4、数据运算存在NaN如何应对
              • Q5、如何对数据框进行任意行列增、删、改、查操作
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档