2017-09-20 22 views
4

Ich habe ein Datenframe, dass ich die Datentypen für jede Spalte betrachten.Numpy dtype - Datentyp nicht verstanden

Wenn ich laufen:

In [23]: df.dtype.descr 

Out [24]: [(u'date', '<i8'), (u'open', '<f8'), (u'high', '<f8'), (u'low', '<f8'), (u'close', '<f8'), (u'volume', '<f8'), (u'dividend', '<f8'), (u'adj_factor', '<f8'), (u'split_factor', '<f8'), (u'liq', '<f8'), (u'currency', '|O')] 

ich die Währung dtype auf S7 einstellen möchten. Ich mache:

In [25]: dtype_new[-1] = (u'currency', "|S7") 
In [26]: print dtype_new 
Out [27]: [(u'date', '<i8'), (u'open', '<f8'), (u'high', '<f8'), (u'low', '<f8'), (u'close', '<f8'), (u'volume', '<f8'), (u'dividend', '<f8'), (u'adj_factor', '<f8'), (u'split_factor', '<f8'), (u'liq', '<f8'), (u'currency', '|S7')] 

Es scheint das richtige Format zu sein. Also versuche ich es zu meiner df zu setzen:

In [28]: df = df.astype(np.dtype(dtype_new)) 

Und ich bekomme die Fehlermeldung:

TypeError('data type not understood',) 

Was soll ich zu ändern werden? Vielen Dank. Dies hat funktioniert, bevor ich kürzlich Anaconda aktualisiert habe und mir das Problem nicht bekannt ist. Vielen Dank.

EINSTELLUNG:

df.dtype ist

In [23]: records.dtype 
Out[23]: dtype((numpy.record, [(u'date', '<i8'), (u'open', '<f8'), (u'high',  '<f8'), (u'low', '<f8'), (u'close', '<f8'), (u'volume', '<f8'), (u'dividend', '<f8'), (u'adj_factor', '<f8'), (u'split_factor', '<f8'), (u'liq', '<f8'), (u'currency', 'O')])) 

Wie kann ich die '0' in eine Zeichenfolge weniger als 7 Zeichen ändern?

Wie kann ich den letzten dtype von 'O' auf etwas anderes ändern? Insbesondere eine Zeichenfolge mit weniger als 7 Zeichen.

LASTLY - ist das ein Unicode-Problem? Mit Unicode:

In [38]: np.dtype([(u'date', '<i8')]) 
    ...: 
    --------------------------------------------------------------------------- 
TypeError         Traceback (most recent call  last) 
<ipython-input-38-8702f0c7681f> in <module>() 
----> 1 np.dtype([(u'date', '<i8')]) 

TypeError: data type not understood 

Keine Unicode:

In [39]: np.dtype([('date', '<i8')]) 
Out[39]: dtype([('date', '<i8')]) 
+0

Es funktioniert für mich mit 'np.ones (1, dtype = df.dtype)'. Ich frage mich, ob das Problem mit dem Wert in diesem Feld ist. Auch ich benutze Py3. – hpaulj

+0

Ich bin auf Py2 - es funktionierte vor dem numpy Upgrade ich lief. – user1911092

+4

Haben Sie überlegt, ein minimales Arbeitsbeispiel zu erstellen? Welche genauen Versionen laufen auch? – norok2

Antwort

6

Es scheint, dass Sie den Punkt über Unicode und eigentlich zentriert haben, scheinen Sie auf einen wunden Punkt berührt zu haben.

Beginnen wir mit der letzten Dokumentation.

Die Dokumentation dtypes besagt, dass:

[(field_name, field_dtype, field_shape), ...]

obj should be a list of fields where each field is described by a tuple of length 2 or 3. (Equivalent to the descr item in the __array_interface__ attribute.)

The first element, field_name , is the field name (if this is '' then a standard field name, 'f#', is assigned). The field name may also be a 2-tuple of strings where the first string is either a “title” (which may be any string or unicode string) or meta-data for the field which can be any object, and the second string is the “name” which must be a valid Python identifier. The second element, field_dtype , can be anything that can be interpreted as a data-type. The optional third element field_shape contains the shape if this field represents an array of the data-type in the second element. Note that a 3-tuple with a third argument equal to 1 is equivalent to a 2-tuple. This style does not accept align in the dtype constructor as it is assumed that all of the memory is accounted for by the array interface description.

Also das doc nicht wirklich zu geben scheint, ob der Feldname Unicode sein können, was wir von der doc sicher sein kann, ist, dass, wenn definieren wir ein Tupel als Feldname, z ((u'date', 'date'), '<i8'), dann Unicode als "Titel" (Hinweis, immer noch nicht für den Namen!), Führt zu keinen Fehlern.
Andernfalls, auch in diesem Fall, wenn Sie ((u'date', u'date'), '<i8') definieren, erhalten Sie einen Fehler.

Jetzt können Sie Unicode-Namen in Py2 verwenden, indem die encode("ascii")

(u'date'.encode("ascii")) 

verwenden und diese funktionieren sollte.
Ein wichtiger Punkt ist, dass für Py2, Numpy nicht erlaubt, dtype mit Unicode-Feldnamen als Liste von Tupeln anzugeben, aber erlaubt es Wörterbücher zu verwenden.

Wenn ich nicht Unicode-Namen in Py2 nicht verwenden, kann ich das letzte Feld |0-|S7 ändern oder Sie haben die encode("ascii") verwenden, wenn Sie den Namen als Unicode-String definieren.


und die beteiligten Bugs ...

Um zu verstehen, warum es passiert, was Sie sehen, ist es nützlich, einen Blick auf die Fehler/Probleme in Numpy berichtet zu haben und Pandas und die relative Diskussionen.

Numpy
https://github.com/numpy/numpy/issues/2407
Sie können in der Diskussion feststellen (was ich hier nicht berichten), vor allem ein paar Dinge:

  • das „Problem“ wurde für eine Weile los
  • ein Trick Menschen verwendet wurde encode("ascii") auf der Unicode-Zeichenfolge
  • nicht vergessen, dass die 'whatever' Zeichenfolge hat verschiedene Standardeinstellungen (Bytes/Unic ode) in Py2/3
  • @hpaulj selbst kommentierte schön in dieser Ausgabe Bericht, dass "Wenn die Dtype-Spezifikation der Liste der Tupel Typ ist, überprüft es, ob jeder Name eine Zeichenfolge ist (wie durch py2 oder 3 definiert) wenn die dtype Spezifikation ein Wörterbuch ist {'names':[ alist], 'formats':[alist]...}, der py2 Fall ermöglicht auch Unicode-Namen“

Pandas
auch auf der Pandas Seite ein Problem berichtet wurde, die die numpy Frage betrifft: https://github.com/pandas-dev/pandas/pull/13462
Es scheint vor nicht allzu langer Zeit behoben worden zu sein.