2015-06-15 2 views
3

Привет Я создал словарь dataFrame с этим кодомResampling и слияние кадров данных с питоном

import os 
import pandas 
import glob 

path="G:\my_dir\*" 
dataList={} 

for files in glob.glob(path): 
    dataList[files]=(read_csv(files,sep=";",index_col='Date')) 

Различная dataframe присутствует в dictory имеют разные выборки времени. Пример dataFrame (А)

Date    Volume Value 
2014-01-04 06:00:02 6062 108000.0 
2014-01-04 06:06:05 6062 107200.0 
2014-01-04 06:12:07 6062 97400.0 
2014-01-04 06:18:10 6062 99200.0 
2014-01-04 06:24:12 6062 91300.0 
2014-01-04 06:30:14 6062 84100.0 
2014-01-04 06:36:17 6062 57000.0 

Пример dataFrame (B) является

Date    Volume Value 
2014-01-04 05:52:50 6062 4.7 
2014-01-04 05:58:53 6062 4.7 
2014-01-04 06:04:56 6062 4.9 
2014-01-04 06:10:58 6062 5.1 
2014-01-04 06:17:01 6062 5.2 
2014-01-04 06:23:03 6062 5.2 
2014-01-04 06:29:05 6062 5.5 
2014-01-04 06:35:08 6062 5.5 

Различные кадр данных не имеют одинаковое число строк. Я хочу, чтобы объединить различные кадр данных в одном одном, как это:

Data     Volume  B    A    Value(DataframeN) 
2014/04/01 05:52:50  6062  4.70   NaN 
2014/04/01 05:58:53  6062  4.70   NaN 
2014/04/01 06:04:56  6062  4.90   107465.51 
2014/04/01 06:10:58  6062  5.10   100652.60 
2014/04/01 06:17:01  6062  5.20   98899.57 
2014/04/01 06:23:03  6062  5.20   92618.56 
2014/04/01 06:29:05  6062  5.50   85301.73 
2014/04/01 06:35:08  6062  5.50   61523.06 

Я сделал это легко с Matlab, используя с помощью команды

ts_A=timeseries(ValueA,datenum(DateA)); 
ts_B=timeseries(ValueB,datenum(DateB)); 
res_A=resample(ts_A,datenum(DateB)); 

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

Tnx

+0

'append()' или 'concat()'. довольно стандартный, см. документацию. – JohnE

+0

'concat()' не делает resample я думаю. Значения имеют различную выборку времени, которую они должны интерполировать линейным методом. –

+0

Пример, который вы предоставили о том, как вы хотите получить результат, на самом деле не говорит мне, как должны выглядеть данные в конце, не могли бы вы разместить более подробный пример? – firelynx

ответ

4

Вы можете concat два DataFrames, interpolate, затем reindex на DataFrame вы хотите.

Я предполагаю, что у нас есть определенное количество DataFrames, где Date - это DateTimeIndex во всех них. Я буду использовать два в этом примере, так как вы использовали два вопроса, но код будет работать для любого числа.

df_a:

     Volume Value 
Date        
2014-01-04 06:00:02 6062 108000 
2014-01-04 06:06:05 6062 107200 
2014-01-04 06:12:07 6062 97400 
2014-01-04 06:18:10 6062 99200 
2014-01-04 06:24:12 6062 91300 
2014-01-04 06:30:14 6062 84100 
2014-01-04 06:36:17 6062 57000 

df_b:

     Volume Value 
Date        
2014-01-04 05:52:50 6062 4.7 
2014-01-04 05:58:53 6062 4.7 
2014-01-04 06:04:56 6062 4.9 
2014-01-04 06:10:58 6062 5.1 
2014-01-04 06:17:01 6062 5.2 
2014-01-04 06:23:03 6062 5.2 
2014-01-04 06:29:05 6062 5.5 
2014-01-04 06:35:08 6062 5.5 

И вложу их в dict для примера. Вы читаете их непосредственно в dict, поэтому вам не нужно делать этот шаг. Я просто хочу показать, как отформатирован мой пример dict. dictkeys не имеет значения, любой действительный dictkey будет работать:

dataList = {'a': df_a, 
      'b': df_b} 

Это возвращает нас туда, где вы сейчас находитесь, с моей dataList надеюсь, имея один и тот же формат, как и ваша.

Первое, что вам нужно сделать, это объединить DataFrames. Я использую dictkeys как имена столбцов MultiIndex, поэтому вы можете отслеживать, какой экземпляр данного столбца пришел, из которого DataFrame. Вы можете сделать это следующим образом:

df = pd.concat(dataList.values(), axis=1, keys=dataList.keys()) 

Это дает вам DataFrame так:

      a    b  
        Volume Value Volume Value 
Date           
2014-01-04 05:52:50 NaN  NaN 6062 4.7 
2014-01-04 05:58:53 NaN  NaN 6062 4.7 
2014-01-04 06:00:02 6062 108000 NaN NaN 
2014-01-04 06:04:56 NaN  NaN 6062 4.9 
2014-01-04 06:06:05 6062 107200 NaN NaN 
2014-01-04 06:10:58 NaN  NaN 6062 5.1 
2014-01-04 06:12:07 6062 97400 NaN NaN 
2014-01-04 06:17:01 NaN  NaN 6062 5.2 
2014-01-04 06:18:10 6062 99200 NaN NaN 
2014-01-04 06:23:03 NaN  NaN 6062 5.2 
2014-01-04 06:24:12 6062 91300 NaN NaN 
2014-01-04 06:29:05 NaN  NaN 6062 5.5 
2014-01-04 06:30:14 6062 84100 NaN NaN 
2014-01-04 06:35:08 NaN  NaN 6062 5.5 
2014-01-04 06:36:17 6062 57000 NaN NaN 

Далее необходимо интерполировать для заполнения недостающих значений.Я интерполирую с использованием 'time'mode так правильно обрабатывает временные индексы:

df = df.interpolate('time') 

Это дает вам DataFrame так:

      a      b   
        Volume   Value Volume  Value 
Date              
2014-01-04 05:52:50 NaN   NaN 6062 4.700000 
2014-01-04 05:58:53 NaN   NaN 6062 4.700000 
2014-01-04 06:00:02 6062 108000.000000 6062 4.738017 
2014-01-04 06:04:56 6062 107352.066116 6062 4.900000 
2014-01-04 06:06:05 6062 107200.000000 6062 4.938122 
2014-01-04 06:10:58 6062 99267.955801 6062 5.100000 
2014-01-04 06:12:07 6062 97400.000000 6062 5.119008 
2014-01-04 06:17:01 6062 98857.851240 6062 5.200000 
2014-01-04 06:18:10 6062 99200.000000 6062 5.200000 
2014-01-04 06:23:03 6062 92805.801105 6062 5.200000 
2014-01-04 06:24:12 6062 91300.000000 6062 5.257182 
2014-01-04 06:29:05 6062 85472.375691 6062 5.500000 
2014-01-04 06:30:14 6062 84100.000000 6062 5.500000 
2014-01-04 06:35:08 6062 62151.239669 6062 5.500000 
2014-01-04 06:36:17 6062 57000.000000 6062 5.500000 

Я думаю, что в целом было бы лучше остановиться здесь, так как вы держите все данные из всех csv файлов. Но вы сказали, что хотите только моменты времени от самого длинного csv. Чтобы получить это, вам нужно найти самый длинный DataFrame, а затем получить строки, соответствующие его индексам. Найти самый длинный DataFrame легко, вы просто найдете ту, которая имеет максимальную длину. Сохранение только временных моментов в том, что index также легко, вы просто нарезаете его, используя index (вы используете метод loc для нарезки таким образом).

longind = max(dataList.values(), key=len).index 
df = df.loc[longind] 

Это дает следующее окончательное DataFrame:

      a      b  
        Volume   Value Volume Value 
Date             
2014-01-04 05:52:50 NaN   NaN 6062 4.7 
2014-01-04 05:58:53 NaN   NaN 6062 4.7 
2014-01-04 06:04:56 6062 107352.066116 6062 4.9 
2014-01-04 06:10:58 6062 99267.955801 6062 5.1 
2014-01-04 06:17:01 6062 98857.851240 6062 5.2 
2014-01-04 06:23:03 6062 92805.801105 6062 5.2 
2014-01-04 06:29:05 6062 85472.375691 6062 5.5 
2014-01-04 06:35:08 6062 62151.239669 6062 5.5 

Это могут быть объединены в одну строку, если вы хотите:

df = pd.concat(dataList.values(), axis=1, keys=dataList.keys()).interpolate('time').loc[max(dataList.values(), key=len).index] 

Или, возможно, немного более четкие 4 линии:

names = dataList.keys() 
dfs = dataList.values() 
longind = max(dfs, key=len).index 
df = pd.concat(dfs, axis=1, keys=names).interpolate('time').loc[longind] 

Я не уверен, почему мои окончательные результаты отличаются от того, что вы показываете. Я сам выполнил ваш пример в MATLAB (R2015A) и получил те же результаты, что и я, поэтому я подозреваю, что вы создали окончательные данные с другим набором данных, чем этот пример.

+0

Если я попробую ваше решение, вы получите эту ошибку: ' ValueError: временная взвешенная интерполяция работает только на Series или DataFrames с DatetimeIndex' –

+0

Да, как я уже сказал, «I предположим, что у нас есть два DataFrames, где 'Date' является' DateTimeIndex'. Вы, по-видимому, не используете 'DateTimeIndex'. Убедитесь, что у вас есть' parse_dates = True' и 'index_co l = 'Дата' в вашем вызове 'read_csv'. – TheBlackCat

+0

Хорошо, мне не хватало 'prase_dates = True'. Но с вашим кодом я делаю это только для двух кадров данных. У меня есть словарь с несколькими кадрами данных, которые нужно перепродавать по отношению к самому длинному. Как мне это сделать? –