2017-06-21 1 views
0

meine Frage ist Ursprung von this answer von Phil. der CodeWie bekomme ich <class 'numpy.str'> anstelle von <class 'numpy.object _'>

df = pd.DataFrame([[1,31,2.5,1260759144], [1,1029,3,1260759179], 
        [1,1061,3,1260759182],[1,1129,2,1260759185], 
        [1,1172,4,1260759205],[2,31,3,1260759134], 
        [2,1111,4.5,1260759256]], 
        index=list(['a','c','h','g','e','b','f',]), 
        columns=list(['userId','movieId','rating','timestamp'])) 
df.index.names=['ID No.'] 
df.columns.names=['Information'] 

def df_to_sarray(df): 
    """ 
    Convert a pandas DataFrame object to a numpy structured array. 
    This is functionally equivalent to but more efficient than 
    np.array(df.to_array()) 

    :param df: the data frame to convert 
    :return: a numpy structured array representation of df 
    """ 
    v = df.values 
    cols = df.columns 
# df[k].dtype.type is <class 'numpy.object_'>,I want to convert it to numpy.str 
    types = [(cols[i], df[k].dtype.type) for (i, k) in enumerate(cols)] 
    dtype = np.dtype(types) 
    z = np.zeros(v.shape[0], dtype) 
    for (i, k) in enumerate(z.dtype.names): 
     z[k] = v[:, i] 
    return z 
sa = df_to_sarray(df.reset_index()) 
print(sa) 

Phils Antwort funktioniert gut, während, wenn ich

sa = df_to_sarray(df.reset_index()) 

laufen werde ich folgendes Ergebnis.

array([('a', 1, 31, 2.5, 1260759144), ('c', 1, 1029, 3.0, 1260759179), 
     ('h', 1, 1061, 3.0, 1260759182), ('g', 1, 1129, 2.0, 1260759185), 
     ('e', 1, 1172, 4.0, 1260759205), ('b', 2, 31, 3.0, 1260759134), 
     ('f', 2, 1111, 4.5, 1260759256)], 
     dtype=[('ID No.', 'O'), ('userId', '<i8'), ('movieId', '<i8'), ('rating', '<f8'), ('timestamp', '<i8')]) 

Ich hoffe, ich kann dtype wie folgt erhalten.

dtype=[('ID No.', 'S'), ('userId', '<i8'), ('movieId', '<i8'), ('rating', '<f8'), ('timestamp', '<i8')] 

Zeichenfolge anstelle von Objekt.

Ich habe den Typ von df [k] .dtype.type getestet, ich fand es <class 'numpy.object_'>, ich möchte es in numpy.str konvertieren. wie geht das?

+0

Haben Sie versucht '' 'df [col] .astype (str)' ''? –

+0

'types' ist ein iist. Sie sollten also in der Lage sein, das erste Tupel zu ändern. was vermutlich '(' ID No. ',' O ') ist. – hpaulj

+0

Ich würde nur 'Objekt' Typ in 'String' konvertieren, für andere Spalten mit dem Typ 'int' möchte ich sie als 'int' behalten. – Renke

Antwort

1

Nach reset_index sind die Dtypen Ihres Datenrahmens eine Mischung aus Objekt und Zahlen. Die Indexierung wurde als Objekt und nicht als Zeichenfolgen gerendert.

In [9]: df1=df.reset_index() 
In [10]: df1.dtypes 
Out[10]: 
Information 
ID No.  object 
userId   int64 
movieId  int64 
rating  float64 
timestamp  int64 
dtype: object 

df1.values ist ein (7,5), DTYPE Array-Objekt.

Mit den richtigen dtype, Ihr Ansatz gut funktioniert (ich bin Gebrauch 'U2' auf PY3):

In [31]: v = df1.values 
In [32]: dt1=np.dtype([('ID No.', 'U2'), ('userId', '<i8'), ('movieId', '<i8'), 
    ...: ('rating', '<f8'), ('timestamp', '<i8')]) 
In [33]: z = np.zeros(v.shape[0], dtype=dt1) 
In [34]: 
In [34]: for i,k in enumerate(dt1.names): 
    ...:  z[k] = v[:, i] 
    ...:  
In [35]: z 
Out[35]: 
array([('a', 1, 31, 2.5, 1260759144), ('c', 1, 1029, 3. , 1260759179), 
     ('h', 1, 1061, 3. , 1260759182), ('g', 1, 1129, 2. , 1260759185), 
     ('e', 1, 1172, 4. , 1260759205), ('b', 2, 31, 3. , 1260759134), 
     ('f', 2, 1111, 4.5, 1260759256)], 
     dtype=[('ID No.', '<U2'), ('userId', '<i8'), ('movieId', '<i8'), ('rating', '<f8'), ('timestamp', '<i8')]) 

Also der Trick ist, dass dt1 aus dem Datenrahmen abzuleiten.

Schnitt types nach dem Bau ist eine Option:

In [36]: cols=df1.columns 
In [37]: types = [(cols[i], df1[k].dtype.type) for (i, k) in enumerate(cols)] 
In [38]: types 
Out[38]: 
[('ID No.', numpy.object_), 
('userId', numpy.int64), 
('movieId', numpy.int64), 
('rating', numpy.float64), 
('timestamp', numpy.int64)] 
In [39]: types[0]=(types[0][0], 'U2') 
In [40]: types 
Out[40]: 
[('ID No.', 'U2'), 
('userId', numpy.int64), 
('movieId', numpy.int64), 
('rating', numpy.float64), 
('timestamp', numpy.int64)] 
In [41]: 
In [41]: z = np.zeros(v.shape[0], dtype=types) 

die Säule dtype während der Bauphase Tweaking auch funktioniert:

def foo(atype): 
    if atype==np.object_: 
     return 'U2' 
    return atype 
In [59]: types = [(cols[i], foo(df1[k].dtype.type)) for (i, k) in enumerate(cols)] 

In jedem Fall werden wir im Voraus wissen, dass wir machen wollen die object Spalte in einen bestimmten string Typ, und nicht etwas allgemeiner.

Ich weiß nicht genug pandas zu sagen, ob es möglich ist, die dtype der ID Spalte zu ändern, bevor wir ein Array extrahieren. .values wird aufgrund der Mischung von Spalten-Dtypen ein Objekt dtype sein.

+0

Danke, Ihr Rat funktioniert. – Renke

Verwandte Themen