【发布时间】:2016-11-30 19:23:17
【问题描述】:
给定df
df = pd.DataFrame(np.arange(8).reshape(2, 4), columns=list('abcd'))
假设我需要将列 'b' 放在最后。我可以这样做:
df[['a', 'c', 'd', 'b']]
但是确保给定列位于末尾的最有效方法是什么?
这就是我一直在做的事情。别人会怎么做?
def put_me_last(df, column):
return pd.concat([df.drop(column, axis=1), df[column]], axis=1)
put_me_last(df, 'b')
计时结果
结论
mfripp 是赢家。似乎reindex_axis 比[] 效率提高很多。这是非常好的信息。
代码
from string import lowercase
df_small = pd.DataFrame(np.arange(8).reshape(2, 4), columns=list('abcd'))
df_large = pd.DataFrame(np.arange(1000000).reshape(10000, 100),
columns=pd.MultiIndex.from_product([list(lowercase[:-1]), ['One', 'Two', 'Three', 'Four']]))
def pir1(df, column):
return pd.concat([df.drop(column, axis=1), df[column]], axis=1)
def pir2(df, column):
if df.columns[-1] == column:
return df
else:
pos = df.columns.values.__eq__('b').argmax()
return df[np.roll(df.columns, len(df.columns) - 1 - pos)]
def pir3(df, column):
if df.columns[-1] == column:
return df
else:
pos = df.columns.values.__eq__('b').argmax()
cols = df.columns.values
np.concatenate([cols[:pos], cols[1+pos:], cols[[pos]]])
return df[np.concatenate([cols[:pos], cols[1+pos:], cols[[pos]]])]
def pir4(df, column):
if df.columns[-1] == column:
return df
else:
return df[np.roll(df.columns.drop(column).insert(0, column), -1)]
def carsten1(df, column):
cols = list(df)
if cols[-1] == column:
return df
else:
return pd.concat([df.drop(column, axis=1), df[column]], axis=1)
def carsten2(df, column):
cols = list(df)
if cols[-1] == column:
return df
else:
idx = cols.index(column)
new_cols = cols[:idx] + cols[idx + 1:] + [column]
return df[new_cols]
def mfripp1(df, column):
new_cols = [c for c in df.columns if c != column] + [column]
return df[new_cols]
def mfripp2(df, column):
new_cols = [c for c in df.columns if c != column] + [column]
return df.reindex_axis(new_cols, axis='columns', copy=False)
def ptrj1(df, column):
return df.reindex(columns=df.columns.drop(column).append(pd.Index([column])))
def shivsn1(df, column):
column_list=list(df)
column_list.remove(column)
column_list.append(column)
return df[column_list]
def merlin1(df, column):
return df[df.columns.drop(["b"]).insert(99999, 'b')]
list_of_funcs = [pir1, pir2, pir3, pir4, carsten1, carsten2, mfripp1, mfripp2, ptrj1, shivsn1]
def test_pml(df, pml):
for c in df.columns:
pml(df, c)
summary = pd.DataFrame([], [f.__name__ for f in list_of_funcs], ['Small', 'Large'])
for f in list_of_funcs:
summary.at[f.__name__, 'Small'] = timeit(lambda: test_pml(df_small, f), number=100)
summary.at[f.__name__, 'Large'] = timeit(lambda: test_pml(df_large, f), number=10)
【问题讨论】:
-
尝试将您的备选方案与
timeit模块进行比较。 -
@mhawke 我计划这样做。这就是我将如何决定答案。
-
那么到目前为止,您的 2 个替代方案中哪个更快?
-
我正在做测试。我必须随机化列顺序并在不同大小的数据集上测试许多试验。今晚我要一个。
-
@mhawke 到目前为止,唯一的答案只有在该列已经是最后一列时才会受益。在随机设置中,它将获得 1 / len(columns) 的时间。根据列的数量,收益可能不会超过检查成本。无论如何,我会建立一个适当的测试。