2017-01-06 7 views
5

Wejście do pd.read_clipboard()Błąd parsowania, zaktualizuj wiele kolumn w 1 linia

Ratanhia ,30c x2, 200c x2 
Aloe ,30c x2, 200c x2 
Nitric Acid ,30c x2, 200c x 2 
Sedum Acre ,200c x2, 30c x2 
Paeonia ,200c x2, 30c x2 
Sulphur ,200c x2, 30c x2 
Hamamelis ,30c x1, 200c x1 
Aesculus ,30c x1, 200c x1⁠⁠⁠⁠ 

Kod:

import pandas as pd 

df = pd.read_clipboard(header=None, sep=',') 
df.columns = ['Medicine','power30c','power200c'] 
df.power30c=df.power30c.apply(lambda x: x[-1]) 
df.power200c=df.power200c.apply(lambda x: x[-1]) 
print df 

wyjścia:

 Medicine power30c power200c 
0  Ratanhia   2   2 
1   Aloe   2   2 
2 Nitric Acid   2   2 
3 Sedum Acre   2   2 
4  Paeonia   2   2 
5  Sulphur   2   2 
6 Hamamelis   1   1 
7  Aesculus   1   � 

Pytania:

  1. Dlaczego to w ostatnim rzędzie?
  2. Jak zmodyfikować więcej niż 1 kolumnę w 1 linii?
df[['power30c','power200c']] = df[['power30c','power200c']].apply(lambda x: x[-1]) 

Throws error: 

ValueError: Length mismatch: Expected axis has 1 elements, new values have 3 elements 

Python Wersja: 2.7, Pandy: 0,19, ipython: 4

+0

co się dzieje, jeśli istnieje nowa linia po ostatniej linii? – piRSquared

+0

@piRSquared \t Rozwiązany. Skopiowałem ten tekst z WhatsApp. To był powód. Ostatnie 'x1' było czymś innym pod maską. – MYGz

Odpowiedz

2

Trzeba parametr skipinitialspace:

df = pd.read_clipboard(sep=',', 
         names=['Medicine','power30c','power200c'], 
         skipinitialspace=True) 
print (df) 
     Medicine power30c power200c 
0  Ratanhia 30c x2 200c x2 
1   Aloe 30c x2 200c x2 
2 Nitric Acid 30c x2 200c x 2 
3 Sedum Acre 200c x2 30c x2 
4  Paeonia 200c x2 30c x2 
5  Sulphur 200c x2 30c x2 
6 Hamamelis 30c x1 200c x1 
7  Aesculus 30c x1 200c x1 

A potem indexing with str:

df[['power30c','power200c']] = df[['power30c','power200c']].apply(lambda x: x.str[-1]) 
print (df) 
     Medicine power30c power200c 
0  Ratanhia   2   2 
1   Aloe   2   2 
2 Nitric Acid   2   2 
3 Sedum Acre   2   2 
4  Paeonia   2   2 
5  Sulphur   2   2 
6 Hamamelis   1   1 
7  Aesculus   1   1 
+0

Dzięki. Nadal dostaję to ' '. – MYGz

+0

Nadal otrzymuję to po 'skipinitialspace'. Brb za jakiś czas. – MYGz

+0

Używam firefox, win7 i dla mnie działa dobrze ... – jezrael

1

Na końcu opublikowanego tekstu znajduje się kilka znaków. Jeśli zrobisz kopię stąd to działa:

Ratanhia ,30c x2, 200c x2 
Aloe ,30c x2, 200c x2 
Nitric Acid ,30c x2, 200c x 2 
Sedum Acre ,200c x2, 30c x2 
Paeonia ,200c x2, 30c x2 
Sulphur ,200c x2, 30c x2 
Hamamelis ,30c x1, 200c x1 
Aesculus ,30c x1, 200c x1 

Gdy używam tekst, który pisał, można zobaczyć dodatkowe znaki:

In [88]: df.power200c[6] 
Out[88]: '200c x1' 
In [89]: df.power200c[7] 
Out[89]: '200c x1\xe2\x81\xa0\xe2\x81\xa0\xe2\x81\xa0\xe2\x81\xa0' 
+0

Rozwiązane. Skopiowałem ten tekst z WhatsApp. To był powód. Ostatnie 'x1' było czymś innym pod maską. – MYGz

1

To jest błąd składni

Ratanhia ,30c x2, 200c x2 
    Aloe ,30c x2, 200c x2 
    Nitric Acid ,30c x2, 200c x2 
    Sedum Acre ,200c x2, 30c x2 
    Paeonia ,200c x2, 30c x2 
    Sulphur ,200c x2, 30c x2 
    Hamamelis ,30c x1, 200c x1 
    Aesculus ,30c x1, 200c x1 

Ostatni znak w tabeli odnoszący się do non-utf-8. Proszę znaleźć poprawiony jeden powyżej. Po rozwiązaniu ten problem z niedopasowaniem długości rozwiązany automatycznie.

+0

Rozwiązane. Skopiowałem ten tekst z WhatsApp. To był powód. Ostatnie 'x1' było czymś innym pod maską. – MYGz

1

Myślę, że te rozwiązania nie uwzględniają faktu, że mają mieszane dane w „moc” * kolumny:

 Medicine power30c power200c 
0  Ratanhia 30c x2 200c x2 
1   Aloe 30c x2 200c x2 
2 Nitric Acid 30c x2 200c x 2 
3 Sedum Acre 200c x2 30c x2 #/NOTE: mixed up values 
4  Paeonia 200c x2 30c x2 # < "200c" is in the "power30c" column 
5  Sulphur 200c x2 30c x2 # \ and "30c" is in the "power200c" column 
6 Hamamelis 30c x1 200c x1 
7  Aesculus 30c x1 200c x1 

Oto kolejny rozwiązanie:

In [34]: df 
Out[34]: 
     Medicine power30c  power200c 
0  Ratanhia 30c x2  200c x2 
1   Aloe 30c x2  200c x2 
2 Nitric Acid 30c x2  200c x 2 
3 Sedum Acre 200c x2  30c x2 
4  Paeonia 200c x2  30c x2 
5  Sulphur 200c x2  30c x2 
6 Hamamelis 30c x1  200c x1 
7  Aesculus 30c x1 200c x1⁠⁠⁠⁠ 

In [35]: (df.set_index('Medicine') 
    ...: .stack() 
    ...: .str.extract(r'(\d+)c\s+x\s*(\d+)', expand=True) 
    ...: .reset_index(level=1, drop=1) 
    ...: .pivot(columns=0, values=1) 
    ...: .add_prefix('power') 
    ...: .add_suffix('c') 
    ...: .reset_index() 
    ...:) 
    ...: 
Out[35]: 
0  Medicine power200c power30c 
0  Aesculus   1  1 
1   Aloe   2  2 
2 Hamamelis   1  1 
3 Nitric Acid   2  2 
4  Paeonia   2  2 
5  Ratanhia   2  2 
6 Sedum Acre   2  2 
7  Sulphur   2  2 
+0

Jak zauważył Gntoni. Kiedy skopiowałem tekst z WhatsApp, na końcu ostatniego 'x1' dodano 1 dodatkowy znak. To było przyczyną problemu. '30c' to potencja i' x2' jest mnożone przez '2'. – MYGz

+0

@MYGz, mój punkt dotyczył mieszanych wartości w kolumnach 'power30c' i' power200c', na przykład dla: '['Sedum Acre', 'Paeonia', 'Sulphur']' - moje rozwiązanie rozwiązuje ten problem – MaxU

+0

Oh. Chłodny! Ponieważ liczby były takie same, nie zauważyłem. – MYGz