转换Pandas DataFrame列的最佳方法

时间:2017-05-03 19:06:25

标签: python pandas

我是熊猫新手,我想知道完成这项数据转换的最佳方法。下面的方法有效,但我觉得它可以更干净/更有效地完成。

我有Office信息,可以采用以下形式:

  • "<建筑> /<办公>"
  • "<建筑>"
  • <建筑物编号> (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

使用pandas做到这一点的最佳方法是什么?

感谢您的帮助!

2 个答案:

答案 0 :(得分: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

(请记住重命名列。)

答案 1 :(得分: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