DataFrame, problem z series przy używaniu apply. Nie mogę zmienić na int.

0

Witam

Ładuje plik.csv za pomocą csv_read().

df = pd.read_csv('dane_ze_strony.csv',
    sep=',',
    encoding="ISO-8859-1",
    skiprows=[],
    dtype={'T': 'int', 'O': 'float64', 'H': 'float64', 'L': 'float64', 'C': 'float64', 'V': 'float64'},
    usecols=['T', 'O', 'H', 'L', 'C', 'V'],
    converters={})

W pierwszej kolumnie jest podany czas w milisekundach.
Po użyciu print( df ['T'] ), w konsoli wyświetla:
0 1465082880
1 1465142880
2 1465202880
2251503 -883690592
Name: T, Length: 2251504, dtype: int32

Problem 1
Dlaczego końcowe rekordy są zamieniane na liczbę ujemną, kiedy jest ich dużo?
Przy małej liczbie działa.

Napisałem sobie funkcje przetwarzającą sekundy na date.

def zamien_milisekundy_na_date(liczba_sekund):
    czas = datetime.datetime.fromtimestamp(liczba_sekund/1000.0)
    return czas

Używam jej przez apply.
df.T = df.T.apply(zamien_milisekundy_na_date)
I dostaje błąd:
cannot convert the series to <class 'int'>

Ale przecież chwile wcześniej przy wyprintowaniu kolumny typ danych był dtype: int32 ?!
Jak użyć DataFrame dla dużej liczby rekordów i jak zmienić sekundy na date??

Dzięki
Pozdrawiam

kod.PNGterminal.JPG

0

Podaj przykładowy plik csv, żeby zreprodukować.

0

@lion137: Zreprodukować to znaczy co? Nic nie zrozumiałem.

0

Daj jakiś skromny plik csv, żeby zreprodukować, odtworzyć, problem; nie rozumiesz znaczenia tego słowa?
https://sjp.pwn.pl/doroszewski/zreprodukowac;5531485.html

0

@lion137: Użyłem pliku z 10 wierszami, ten sam błąd.

1

To go pokaż, ten plik.

3

@asd_asd: wrzuć tutaj jakiś plik (choćby ten z 10 wierszami), który będzie można wziąć, przeanalizować i uruchomić z nim kod. Możesz dodać go jako załącznik w poście.

Na szybko spróbowałem zreprodukować Twój problem, ale składając DataFrame z ręki zamiast czytać z CSV i nic takiego się nie dzieje:

>>> import pandas as pd
>>> df = pd.DataFrame({"a": [1,2], "b": [3,4]})
>>> df.a
0    1
1    2
Name: a, dtype: int64
>>> type(df.a)
<class 'pandas.core.series.Series'>
>>> def foo(x):
...   return x + 0.1
... 
>>> df.a = df.a.apply(foo)
>>> df.a
0    1.1
1    2.1
Name: a, dtype: float64
>>> 

Przypuszczam, że problem może być w zawartości tego CSV lub w specyfice budowania DataFrame z CSV, choć w to drugie raczej wątpię.

Dla wyjaśnienia:

  • df.T powinno zwrócić obiekt Series dla danej kolumny
  • Series.apply(func) powinno wywołać funkcję func dla każdego elementu obiektu Series, na którym to wołasz
  • każdy element Series powinien być skalarem (pojedynczą wartością)

Jeśli u Ciebie coś się wywala, możliwe że któryś z tych warunków nie jest prawdziwy i proponuję sprawdzić je po kolei (np. debuggerem)

4
asd_asd napisał(a):

Po użyciu print( df ['T'] ), w konsoli wyświetla:
0 1465082880
1 1465142880
2 1465202880
2251503 -883690592
Name: T, Length: 2251504, dtype: int32

Jak duże są liczby w tej CSVce? Jest spora szansa, że zwyczajnie przepełniłeś zakres int32 i się "przekręcił" :)

@asd_asd o taki zbieg okoliczności to trzeba się naprawdę postarać :)

pandas.DataFrame.T xD

Coś mnie tak tknęło, że skoro Series można transponować, to DataFrame tym bardziej. A jeśli transpozycję Series można dostać przez atrybut/property pandas.Series.T, to transpozycję DataFrame pewnie też... no i masz. Na 99% w momencie, gdy masz kolumnę nazywającą się identycznie jak atrybut, to atrybut ją zasłania.

W efekcie dostajesz transponowany (czyt. wiersze i kolumny zamienione miejscami) DataFrame zamiast kolumny T:

>>> df = pd.DataFrame({'a': [1, 2], 'T': [3, 4]})
>>> df.T
   0  1
a  1  2
T  3  4
>>> df['T']
0    3
1    4
Name: T, dtype: int64
0

@superdurszlak: Stawiam flache, działa!

1 użytkowników online, w tym zalogowanych: 0, gości: 1