2017-05-03 70 views
1

我是熊貓新手,並且想知道完成這種數據轉換的最佳方法。下面的方法可行,但我有一種感覺,它可以更乾淨/更高效地完成。最好的方式來轉換熊貓DataFrame列

我局的信息,可以在以下形式:

  • 「<建築>/<辦公室>」
  • 「<建設>」
  • <樓號>(INT)
  • ''(空字符串)

我想將其轉換爲Building和Office列。

鑑於數據:

df = pandas.DataFrame({ "Office" : [ "Building Foo/10", "Building Only", None, 100, ""]}) 
df 

    Office 
0 Building Foo/10 
1 Building Only 
2 None 
3 100 
4 

我可以通過改造它:

items = [ (str(row["Office"]) or '').rsplit('/', 1) for _, row in df.iterrows() ] 
items = [ item if len(item) == 2 else (item[0] or None, None) for item in items ] 

df["Building"], df["Office"] = zip(*items) 
df 

    Office Building 
0 10  Building Foo 
1 None Building Only 
2 None None 
3 None 100 
4 None None 

什麼是做這個用熊貓的最佳方式?

感謝您的幫助!

+0

IMO你的數據幀是錯誤的。每個辦公室在框架中都需要自己的行。你知道一個系列是什麼嗎? DataFrame是_n_ Series的表格。 – Elmex80s

回答

0

有可能做到這一點沒有最好方式,但這裏有一個足夠好的:

pd.DataFrame([(None,None) if not o else 
       (None, o) if isinstance(o, int) else 
       tuple(o.split("/")) for o in df.Office], 
      columns=("Building", "Office")) 
#  Building Office 
#0 Building Foo  10 
#1 Building Only None 
#2   None None 
#3   None 100 
#4   None None 

您可以apply達到同樣的效果。後一種方法保留行索引:

df['Office'].apply(lambda x: 
        pd.Series((None,None) if not x else 
          (None, x) if isinstance(x, int) else 
          tuple(x.split("/")))) 
#    0  1 
#0 Building Foo 10 
#1 Building Only NaN 
#2   None None 
#3   None 100 
#4   None None 

(請記住重命名列)。

0

我會做這種方式:

In [99]: df.Office = df.Office.astype(str) 

In [100]: df[['Building','Office']] = \ 
       df.Office.str.replace(r'(\d+)', r'/\1').str.split(r'\/+', expand=True) 

In [101]: df 
Out[101]: 
    Office  Building 
0  10 Building Foo 
1 None Building Only 
2 None   None 
3 100 
4 None