切片数据框返回意外结果

时间:2018-06-28 20:42:45

标签: python pandas slice nan

我有13个CSV文件,其中包含非常规格式的帐单信息。每天每30分钟记录一次多次读数。彼此相邻(列)记录了五天。然后将接下来的五天记录在其下。为了使事情变得更复杂,每天的第一个KVAR记录都会显示星期几,日期和帐单日。

图像打击显示了一个小例子。但是,假设KW,KVAR和KVA再重复3次,然后再继续行约50行。

For Example

我的目标是创建一个简单的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循环中列移位的第一个实例)之后数据开始分解的位置。我在做什么错了?

output

1 个答案:

答案 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.meltpd.groupby将其成形为所需的格式。或者,如果坚持使用熊猫I / O,则尝试使用多索引。