我有13个CSV文件,其中包含非常规格式的帐单信息。每天每30分钟记录一次多次读数。彼此相邻(列)记录了五天。然后将接下来的五天记录在其下。为了使事情变得更复杂,每天的第一个KVAR记录都会显示星期几,日期和帐单日。
图像打击显示了一个小例子。但是,假设KW,KVAR和KVA再重复3次,然后再继续行约50行。
我的目标是创建一个简单的python脚本,该脚本会将数据放入具有DATE,TIME,KW,KVAR,KVA和DAY列的数据框中。
问题是我的脚本在前五天(与for循环的新实例相关)之后返回了KW,KVAR和KVA数据的NaN数据。我感到奇怪的是,当我尝试打印相同的范围时,我得到了我期望的数据。
我的代码如下。我添加了评论以帮助进一步解释。我也有一个示例函数示例输出。
def make_df(df):
#starting values
output = pd.DataFrame(columns=["DATE", "TIME", "KW", "KVAR", "KVA", "DAY"])
time = df1.loc[3:50,0]
val_start = 3
val_end = 51
date_val = [0,2]
day_type = [1,2]
# There are 7 row movements that need to take place.
for row_move in range(1,8):
day = [1,2,3]
date_val[1] = 2
day_type[1] = 2
# There are 5 column movements that take place.
# The basic idea is that I would cycle through the five days, grab their data in a temporary dataframe,
# and then append that dataframe onto the output dataframe
for col_move in range(1,6):
temp_df = pd.DataFrame(columns=["DATE", "TIME", "KW", "KVAR", "KVA", "DAY"])
temp_df['TIME'] = time
#These are the 3 values that stop working after the first column change
# I get the values that I expect for the first 5 days
temp_df['KW'] = df.iloc[val_start:val_end, day[0]]
temp_df['KVAR'] = df.iloc[val_start:val_end, day[1]]
temp_df['KVA'] = df.iloc[val_start:val_end, day[2]]
# These 2 values work perfectly for the entire data set
temp_df['DAY'] = df.iloc[day_type[0], day_type[1]]
temp_df["DATE"] = df.iloc[date_val[0], date_val[1]]
# trouble shooting
print(df.iloc[val_start:val_end, day[0]])
print(temp_df)
output = output.append(temp_df)
# increase values for each iteration of row loop.
# seems to work perfectly when I print the data
day = [x + 3 for x in day]
date_val[1] = date_val[1] + 3
day_type[1] = day_type[1] + 3
# increase values for each iteration of column loop
# seems to work perfectly when I print the data
date_val[0] = date_val[0] + 55
day_type [0]= day_type[0] + 55
val_start = val_start + 55
val_end = val_end + 55
return output
test = make_df(df1)
下面是一些示例输出。它显示了第五天(或for循环中列移位的第一个实例)之后数据开始分解的位置。我在做什么错了?
答案 0 :(得分:1)
可能是pd.append
,要求数值具有匹配的行索引。
import pandas as pd
import numpy as np
output = pd.DataFrame(np.random.rand(5,2), columns=['a','b']) # fake data
output['c'] = list('abcdefghij') # add a column of non-numerical entries
tmp = pd.DataFrame(columns=['a','b','c'])
tmp['a'] = output.iloc[0:2, 2]
tmp['b'] = output.iloc[3:5, 2] # generates NaN
tmp['c'] = output.iloc[0:2, 2]
data.append(tmp)
(初始响应)
df1
的外观如何? df.iloc[val_start:val_end, day[0]]
在第五天之后有任何问题吗?这些代码未显示您如何从csv文件或df1
本身读取数据。
我的猜测:如果val_start:val_end
在第六天给出了无效的索引,或者df1
在第五天之后出现格式错误,则df.iloc[val_start:val_end, day[0]]
将返回一个空的Series对象,并可能使其进入temp_df
。尽管类似的列索引会触发IndexError,但是iloc
不会报告无效的行索引。
import numpy as np
import pandas as pd
df = pd.DataFrame(np.random.rand(5,3), columns=['a','b','c'], index=np.arange(5)) # fake data
df.iloc[0:2, 1] # returns the subset
df.iloc[100:102, 1] # returns: Series([], Name: b, dtype: float64)
有点偏离主题,但我建议预处理csv文件,而不要处理Pandas DataFrame中的索引,因为原始格式有点复杂。按日期对数据进行切片,然后使用pd.melt
或pd.groupby
将其成形为所需的格式。或者,如果坚持使用熊猫I / O,则尝试使用多索引。