2016-07-18 10 views
9

Mam dyktafon, który przechowuje obliczone wartości w różnych odstępach czasu, co oznacza, że ​​zaczynają się w różnych datach. Na przykład, dane mam może wyglądać następująco:Wypełnianie dicta wartościami NA, aby umożliwić konwersję na pandasową ramkę danych

Date  col1 col2 col3 col4 col5 
01-01-15 5  12  1  -15  10 
01-02-15 7  0  9  11  7 
01-03-15   6  1  2  18 
01-04-15   9  8  10 
01-05-15   -4    7 
01-06-15   -11    -1 
01-07-15   6    

Gdzie każdy nagłówek jest kluczem, a każda kolumna wartości jest wartość dla każdego klucza (używam defaultdict(list) do tego). Kiedy próbuję uruchomić pd.DataFrame.from_dict(d), zrozumiałe jest, że wystąpił błąd stwierdzający, że wszystkie tablice muszą mieć tę samą długość. Czy istnieje prosty/trywialny sposób wypełnienia lub wypełnienia liczb tak, aby wynik końcowy był następującą ramką danych?

Date  col1 col2 col3 col4 col5 
01-01-15 5  12  1  -15  10 
01-02-15 7  0  9  11  7 
01-03-15 NaN  6  1  2  18 
01-04-15 NaN  9  8  10  NaN 
01-05-15 NaN -4  NaN  7  NaN 
01-06-15 NaN -11  NaN -1  NaN 
01-07-15 NaN  6  NaN  NaN  NaN 

Czy będę musiał zrobić to ręcznie z każdą listą?

Oto kod, aby odtworzyć słownika:

import pandas as pd 
from collections import defaultdict 

d = defaultdict(list) 
d["Date"].extend([ 
    "01-01-15", 
    "01-02-15", 
    "01-03-15", 
    "01-04-15", 
    "01-05-15", 
    "01-06-15", 
    "01-07-15" 
] 
d["col1"].extend([5, 7]) 
d["col2"].extend([12, 0, 6, 9, -4, -11, 6]) 
d["col3"].extend([1, 9, 1, 8]) 
d["col4"].extend([-15, 11, 2, 10, 7, -1]) 
d["col5"].extend([10, 7, 18]) 
+2

Czy możesz dodać kod, który mógłby ponownie utworzyć przykładowy dyktat? Poza tym przez N/A masz na myśli NaNs? – Divakar

+0

Łatwo uzyskasz odpowiedź od jednego z nas, jeśli wykonasz trochę pracy na nogach i udostępnisz kod, do którego odnosi się @Divakar. – piRSquared

+0

Właśnie dodano. I tak, miałem na myśli NaN. Przepraszamy, spędzam zbyt dużo czasu w programie Excel. – weskpga

Odpowiedz

8

Inną opcją jest użycie from_dict z orient='index' a następnie podjąć tranpose:

my_dict = {'a' : [1, 2, 3, 4, 5], 'b': [1, 2, 3]} 
df = pd.DataFrame.from_dict(my_dict, orient='index').T 

Pamiętaj, że możesz napotkać problemy z dtype, jeśli kolumny mają różne typy, np. unosi się w jednej kolumnie, ciągi w drugiej.

wyjście Wynikające:

 a b 
0 1.0 1.0 
1 2.0 2.0 
2 3.0 3.0 
3 4.0 NaN 
4 5.0 NaN 
+0

Kilka świetnych odpowiedzi tutaj, ale myślę, że to jest najlepsze. – weskpga

+0

W następstwie tego, czy istnieje prosty sposób na kontynuowanie 'NaN's zamiast dołączania ich do końca? – weskpga

5
#dictionary of different lengths... 
my_dict = {'a' : [1, 2, 3, 4, 5], 'b': [1, 2, 3]} 
pd.DataFrame(dict([(col_name,pd.Series(values)) for col_name,values in my_dict.items() ])) 

Wyjście -

a b 
0 1 1.0 
1 2 2.0 
2 3 3.0 
3 4 NaN 
4 5 NaN 
5

Oto podejście stosując maskowanie -

K = d.keys() 
V = d.values() 

mask = ~np.in1d(K,'Date') 
K1 = [K[i] for i,item in enumerate(V) if mask[i]] 
V1 = [V[i] for i,item in enumerate(V) if mask[i]] 

lens = np.array([len(item) for item in V1]) 
mask = lens[:,None] > np.arange(lens.max()) 

out_arr = np.full(mask.shape,np.nan) 
out_arr[mask] = np.concatenate(V1) 
df = pd.DataFrame(out_arr.T,columns=K1,index=d['Date']) 

run Sample -

In [612]: d.keys() 
Out[612]: ['col4', 'col5', 'col2', 'col3', 'col1', 'Date'] 

In [613]: d.values() 
Out[613]: 
[[-15, 11, 2, 10, 7, -1], 
[10, 7, 18], 
[12, 0, 6, 9, -4, -11, 6], 
[1, 9, 1, 8], 
[5, 7], 
['01-01-15', 
    '01-02-15', 
    '01-03-15', 
    '01-04-15', 
    '01-05-15', 
    '01-06-15', 
    '01-07-15']] 

In [614]: df 
Out[614]: 
      col4 col5 col2 col3 col1 
01-01-15 -15 10 12  1  5 
01-02-15 11  7  0  9  7 
01-03-15  2 18  6  1 NaN 
01-04-15 10 NaN  9  8 NaN 
01-05-15  7 NaN -4 NaN NaN 
01-06-15 -1 NaN -11 NaN NaN 
01-07-15 NaN NaN  6 NaN NaN 
+0

Po prostu szybka poprawka na literówkę .... powinna być len (pozycja) zamiast len ​​(item [0]) – hashcode55

+0

@ hashcode55 Tak, z tą początkową zaksięgowaną próbką, lista miała wartości osadzone o jeden poziom głębiej. Aktualizuj teraz dla nowej wysłanej próbki, dzięki! – Divakar

5

Z itertools (Python 3):

import itertools 
pd.DataFrame(list(itertools.zip_longest(*d.values())), columns=d.keys()).sort_index(axis=1) 
Out[728]: 
    col1 col2 col3 col4 col5 
0 5.0 12 1.0 -15.0 10.0 
1 7.0  0 9.0 11.0 7.0 
2 NaN  6 1.0 2.0 18.0 
3 NaN  9 8.0 10.0 NaN 
4 NaN -4 NaN 7.0 NaN 
5 NaN -11 NaN -1.0 NaN 
6 NaN  6 NaN NaN NaN 
Powiązane problemy