数据分析实战中遇到的几个问题?
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 = []
#列表生成式截留,其它方法参见推文
#以名称作为筛选字段时,可能出现重复的情况,实际中尽量以字段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))]
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["用电量"])
需求:pandas处理多列相减,实际某些元素本身为空值,如何碰到一个单元格元素为空就忽略了不计算,一般怎么解决!
#构造问题数据源
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)
#如果这样操作,发现所求列为空值,不是我想要的结果
df["照明用电"]=df["电耗量"]-df["空调用电"]-df["动力用电"]-df["特殊用电"]
应该如何处理?
#将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=["分项之和"])
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
# 删
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的行 默认选项为此
# 改
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"]
# 查
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)
方法三:自定义打标签,参加推文