Разрезание моего фрейма данных возвращает неожиданные результаты - PullRequest
0 голосов
/ 28 июня 2018

У меня есть 13 CSV-файлов, которые содержат платежную информацию в необычном формате. Несколько чтений записываются каждые 30 минут дня. Пять дней записываются рядом друг с другом (столбцы). Затем следующие пять дней записываются под ним. Чтобы усложнить задачу, день недели, дата и день выставления счетов отображаются поверх первой записи KVAR каждый день.

Изображение удара показывает небольшой пример. Однако представьте, что KW, KVAR и KVA повторяются еще 3 раза, прежде чем продолжить примерно 50 строк спустя.

For Example

Моя цель - создать простой скрипт на python, который бы преобразовывал данные в фрейм данных со столбцами: DATE, TIME, KW, KVAR, KVA и DAY.

Проблема в том, что мой скрипт возвращает данные NaN для данных KW, KVAR и KVA через первые пять дней (что связано с новым экземпляром цикла for). Что мне странно, так это то, что когда я пытаюсь распечатать те же диапазоны, я получаю ожидаемые данные.

Мой код указан ниже. Я включил комментарии, чтобы помочь дальнейшему объяснению вещей. У меня также есть пример выходных данных моей функции.

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 голосов
/ 29 июня 2018

Может быть 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. iloc не сообщать о недопустимых индексах строк, хотя аналогичные индексы столбцов могут вызвать 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.melt или pd.groupby, чтобы придать им нужный формат. Или, в качестве альтернативы, попробуйте многоиндексный, если придерживаетесь ввода / вывода Pandas.

...