2016-07-22 53 views
4

有一件事我覺得自己不得不經常做,並且讓我感到驚訝的是在熊貓中實現這一點有多困難。假設我需要創建一個帶有指定索引類型和名稱以及列類型和名稱的空DataFrame。 (我可能想稍後填寫它,例如在一個循環中)。我發現,最簡單的方法是爲每列創建一個空的pandas.Series對象,指定它們的dtype s,將它們放入一個字典中指定他們的名字,並將字典傳遞給構造函數DataFrame。像下面這樣。Python熊貓,創建空DataFrame指定列dtypes

def create_empty_dataframe(): 
    index = pandas.Index([], name="id", dtype=int) 
    column_names = ["name", "score", "height", "weight"] 
    series = [pandas.Series(dtype=str), pandas.Series(dtype=int), pandas.Series(dtype=float), pandas.Series(dtype=float)] 
    columns = dict(zip(column_names, series)) 
    return pandas.DataFrame(columns, index=index, columns=column_names) 
    # The columns=column_names is required because the dictionary will in general put the columns in arbitrary order. 

第一個問題。以上真的是最簡單的方法嗎?有這麼多令人費解的事情。我真正想要做的事情,以及我很確定很多人真正想做的事情,如下所示。

df = pandas.DataFrame(columns=["id", "name", "score", "height", "weight"], dtypes=[int, str, int, float, float], index_column="id") 

第二個問題。 Pandas中是否有這種語法?如果沒有,開發者是否考慮支持這樣的東西呢?我感覺它確實應該像這樣簡單(上面的語法)。

回答

3

不幸的是,DateFrame構造函數接受一個dtype描述符,但是你可以通過使用read_csv騙一點:

In [143]: 
import pandas as pd 
import io 
cols=["id", "name", "score", "height", "weight"] 
df = pd.read_csv(io.StringIO(""), names=cols, dtype=dict(zip(cols,[int, str, int, float, float])), index_col=['id']) 
df.info() 

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 0 entries 
Data columns (total 4 columns): 
name  0 non-null object 
score  0 non-null int32 
height 0 non-null float64 
weight 0 non-null float64 
dtypes: float64(2), int32(1), object(1) 
memory usage: 0.0+ bytes 

所以你可以看到,dtypes是否合適,並且根據需要索引設置:

In [145]: 

df.index 
Out[145]: 
Int64Index([], dtype='int64', name='id') 
+0

不錯的作弊!所以你說沒有欺騙,我的複雜方法真的是最簡單的方法嗎? – Ray

+0

我認爲使用'read_csv'是最簡單的方法,與標準的'DataFrame'相比,它具有更大的靈活性,除了你故意讀取一個空文件 – EdChum

1

您可以通過替換它設置一個數據幀的列的D型也:

df['column_name'] = df['column_name'].astype(float) 
1

您可以通過使用列表理解

def create_empty_dataframe(): 
    index = pandas.Index([], name="id", dtype=int) 
    # specify column name and data type 
    columns = [('name', str), 
       ('score', int), 
       ('height', float), 
       ('weight', float)] 
    # create the dataframe from a dict 
    return pandas.DataFrame({k: pandas.Series(dtype=t) for k, t in columns}) 

這不是在效果上你已經做了完全不同的東西簡單化了一點,但它應該不必是容易使任意數據幀修改代碼中的多個位置。