【问题标题】:Slicing my data frame is returning unexpected results切片我的数据框返回意外结果
【发布时间】:2018-12-08 00:17:07
【问题描述】:

我有 13 个 CSV 文件,其中包含格式异常的帐单信息。每天每 30 分钟记录多个读数。五天并排记录(列)。那么接下来的五天都记录在它下面。为了使事情变得更复杂,星期几、日期和计费日显示在每天的第一次 KVAR 记录上。

图片展示了一个小例子。但是,假设 KW、KVAR 和 KVA 重复 3 次以上,然后再继续大约 50 行。

我的目标是创建一个简单的 Python 脚本,将数据转换为具有以下列的数据框:DATE、TIME、KW、KVAR、KVA 和 DAY。

问题是我的脚本在前五天(与 for 循环的新实例相关)后返回 KW、KVAR 和 KVA 数据的 NaN 数据。对我来说奇怪的是,当我尝试打印出相同的范围时,我得到了我期望的数据。

我的代码如下。我已经包含了 cmets 以帮助进一步解释事情。我还有一个函数的示例输出示例。

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 循环中列移位的第一个实例)。我做错了什么?

【问题讨论】:

    标签: python pandas slice nan


    【解决方案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_dfiloc 不会报告无效的行索引,尽管类似的列索引会触发 IndexError。

    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 将它们塑造成您喜欢的格式。或者如果坚持使用 Pandas I/O,也可以尝试多索引。

    【讨论】:

    • 感谢 Nriuam 的回复。 df.iloc[val_start:val_end, day[0]] 对于 df1 数据框的任何值都会返回我期望的结果。这就是为什么我很困惑。我可以遍历整个数据框并打印出结果,但是当我将值分配给temp_df 时,我得到了 NaN。经过一些预处理后,我将检查 melt 和 groupby。
    • @thomaskh522 看起来pd.append 依赖于索引,就像pd.concat 一样。对于TIME,您使用了df1.loc[3:50,0],然后Pandas 期望分配的所有其他值具有相同的行索引,这会将数值呈现给NaN(字符串不受影响)。在一分钟内将相关测试更新为我的答案。您可以尝试匹配所有列的索引吗?
    • @thomaskh522 抱歉,字符串也可能受到影响(呈现为 NaN),但我仍然怀疑 NaN 是行索引受损的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 2013-07-19
    • 2011-05-19
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    相关资源
    最近更新 更多