Ich habe die folgende CSV-Datei in iPython Notebook eingegeben:
public = pd.read_csv("categories.csv")
public
Ich habe auch Pandas als pd importiert, numpy als np und matplotlib.pyplot als plt. Die folgenden Datentypen sind vorhanden (das Folgende ist eine Zusammenfassung - es gibt ungefähr 100 Spalten)
In [36]: public.dtypes
Out[37]: parks object
playgrounds object
sports object
roading object
resident int64
children int64
Ich möchte "Parks", "Spielplätze", "Sport" und "Roading" in Kategorien umwandeln (in ihnen sind gleichwertige Antworten vorhanden.) Jede Spalte enthält jedoch unterschiedliche Arten von Antworten (z. B. "man stimmt zu") "usw., ein anderer hat" sehr wichtig "," wichtig "usw.), der Rest bleibt als int64.
Ich konnte einen separaten Dataframe - public1 - erstellen und eine der Spalten mithilfe des folgenden Codes in einen Kategorietyp ändern:
public1 = {'parks': public.parks}
public1 = public1['parks'].astype('category')
Als ich jedoch versuchte, eine Nummer mit diesem Code auf einmal zu ändern, war ich nicht erfolgreich:
public1 = {'parks': public.parks,
'playgrounds': public.parks}
public1 = public1['parks', 'playgrounds'].astype('category')
Trotzdem möchte ich keinen separaten Datenrahmen nur mit den Kategoriespalten erstellen. Ich möchte, dass sie im ursprünglichen Datenrahmen geändert wurden.
Ich habe zahlreiche Möglichkeiten ausprobiert, um das zu erreichen, dann habe ich den Code hier ausprobiert: Pandas: Datentyp der Spalten ändern ...
public[['parks', 'playgrounds', 'sports', 'roading']] = public[['parks', 'playgrounds', 'sports', 'roading']].astype('category')
und bekam folgenden Fehler:
NotImplementedError: > 1 ndim Categorical are not supported at this time
Gibt es eine Möglichkeit, "Parks", "Spielplätze", "Sport", "Roading" in Kategorien zu ändern (damit die Antworten der Likert-Skala analysiert werden können), so dass "Einwohner" und "Kinder" (und die 94 anderen Spalten) übrig bleiben sind string, int + floats) bitte unberührt? Oder gibt es einen besseren Weg, dies zu tun? Wenn jemand Anregungen und/oder Rückmeldungen hat, wäre ich sehr dankbar.
Vielen Dank im Voraus.
zum Hinzufügen bearbeitet - Ich benutze Python 2.7.
Manchmal müssen Sie nur eine for-Schleife verwenden:
for col in ['parks', 'playgrounds', 'sports', 'roading']:
public[col] = public[col].astype('category')
Sie können die pandas.DataFrame.apply
-Methode zusammen mit einem lambda
-Ausdruck verwenden, um das Problem zu lösen. In Ihrem Beispiel könnten Sie verwenden
df[['parks', 'playgrounds', 'sports']].apply(lambda x: x.astype('category'))
Ich kenne keinen Weg, um dieses Inplace auszuführen, daher ende ich normalerweise mit einem solchen Element:
df[df.select_dtypes(['object']).columns] = df.select_dtypes(['object']).apply(lambda x: x.astype('category'))
Natürlich können Sie .select_dtypes
durch explizite Spaltennamen ersetzen, wenn Sie nicht alle einen bestimmten Datentyp auswählen möchten (in Ihrem Beispiel scheint es jedoch so, als wollten Sie alle object
-Typen haben).
Ab pandas 0.19.0 beschreibt What's New , dass read_csv
das Analysieren von Categorical
-Spalten direkt unterstützt .. Diese Antwort gilt nur, wenn Sie von read_csv
ausgehen auf 10.000 Datensätzen:
import pandas as pd
import numpy as np
# Generate random data, four category-like columns, two int columns
N=10000
categories = pd.DataFrame({
'parks' : np.random.choice(['strongly agree','agree', 'disagree'], size=N),
'playgrounds' : np.random.choice(['strongly agree','agree', 'disagree'], size=N),
'sports' : np.random.choice(['important', 'very important', 'not important'], size=N),
'roading' : np.random.choice(['important', 'very important', 'not important'], size=N),
'resident' : np.random.choice([1, 2, 3], size=N),
'children' : np.random.choice([0, 1, 2, 3], size=N)
})
categories.to_csv('categories_large.csv', index=False)
pd.read_csv('categories_large.csv').dtypes # inspect default dtypes
children int64
parks object
playgrounds object
resident int64
roading object
sports object
dtype: object
Für gemischtes dtypes
kann das Parsing als Categorical
implementiert werden, indem ein Wörterbuch dtype={'colname' : 'category', ...}
in read_csv
übergeben wird.
pd.read_csv('categories_large.csv', dtype={'parks': 'category',
'playgrounds': 'category',
'sports': 'category',
'roading': 'category'}).dtypes
children int64
parks category
playgrounds category
resident int64
roading category
sports category
dtype: object
Eine leichte Beschleunigung (lokales Jupyter-Notebook), wie in den Versionshinweisen erwähnt.
# unutbu's answer
%%timeit
public = pd.read_csv('categories_large.csv')
for col in ['parks', 'playgrounds', 'sports', 'roading']:
public[col] = public[col].astype('category')
10 loops, best of 3: 20.1 ms per loop
# parsed during read_csv
%%timeit
category_cols = {item: 'category' for item in ['parks', 'playgrounds', 'sports', 'roading']}
public = pd.read_csv('categories_large.csv', dtype=category_cols)
100 loops, best of 3: 14.3 ms per loop
Keine Notwendigkeit für Schleifen, Pandas kann es jetzt direkt tun, übergebe einfach eine Liste der zu konvertierenden Spalten und Pandas konvertiert sie alle.
cols = ['parks', 'playgrounds', 'sports', 'roading']:
public[cols] = public[cols].astype('category')
df = pd.DataFrame({'a': ['a', 'b', 'c'], 'b': ['c', 'd', 'e']})
>> a b
>> 0 a c
>> 1 b d
>> 2 c e
df.dtypes
>> a object
>> b object
>> dtype: object
df[df.columns] = df[df.columns].astype('category')
df.dtypes
>> a category
>> b category
>> dtype: object
In meinem Fall hatte ich einen großen Datenrahmen mit vielen Objekten, die ich in eine Kategorie konvertieren möchte.
Daher habe ich die Objektspalten ausgewählt und alles, was NA ist, als fehlend ausgefüllt und dann im ursprünglichen DataFrame wie in gespeichert
# Convert Object Columns to Categories
obj_df =df.select_dtypes(include=['object']).copy()
obj_df=obj_df.fillna('Missing')
for col in obj_df:
obj_df[col] = obj_df[col].astype('category')
df[obj_df.columns]=obj_df[obj_df.columns]
df.head()
Ich hoffe, dass dies eine hilfreiche Ressource für spätere Referenz sein könnte
Ich fand, dass die Verwendung einer for-Schleife gut funktioniert.
for col in ['col_variable_name_1', 'col_variable_name_2', ect..]:
dataframe_name[col] = dataframe_name[col].astype(float)