假设我有一个包含x和y列的数据框。我想自动将其拆分为与列名称相同的数组(或系列),处理数据,然后重新加入它们。手动执行此操作非常简单:
x, y = df.x, df.y
z = x + y # in actual use case, there are hundreds of lines like this
df = pd.concat([x,y,z],axis=1)
但我想自动化这个。使用df.columns很容易得到一个字符串列表,但我真的想要[x,y]而不是[' x',' y']。到目前为止,我能做的最好的事情就是用exec解决这个问题:
df_orig = DataFrame({ 'x':range(1000), 'y':range(1000,2000), 'z':np.zeros(1000) })
def method1( df ):
for col in df.columns:
exec( col + ' = df.' + col + '.values')
z = x + y # in actual use case, there are hundreds of lines like this
for col in df.columns:
exec( 'df.' + col + '=' + col )
df = df_orig.copy()
method1( df ) # df appears to be view of global df, no need to return it
df1 = df
所以有两个问题:
1)使用这样的exec通常不是一个好主意(当我尝试将它与numba结合时已经给我带来了问题) - 或者那么糟糕?它似乎适用于系列和数组。
2)我不确定在这里利用观点的最佳方式。理想情况下,我真正想要做的就是使用x作为df.x的视图。我假设在x是数组的情况下是不可能的,但如果x是一个数组呢?
上面的示例适用于数组,但理想情况下,我正在寻找也适用于系列的解决方案。取而代之的是,当然欢迎使用其中一种解决方案的解决方案。
动机:
1)可读性,可以用eval部分实现,但我不相信eval可以用于多行?
2)对于像z = x + y这样的多行,这个方法对于系列来说要快一些(在我尝试的例子中是2x或3x),对于数组(超过10x)甚至更快。见这里:Fastest way to numerically process 2d-array: dataframe vs series vs array vs numba
答案 0 :(得分:1)
只需使用索引表示法和字典,而不是使用属性表示法。
df_orig = DataFrame({ 'x':range(1000), 'y':range(1000,2000), 'z':np.zeros(1000) })
def method1( df ):
series = {}
for col in df.columns:
series[col] = df[col]
series['z'] = series['x'] + series['y'] # in actual use case, there are hundreds of lines like this
for col in df.columns:
df[col] = series[col]
df = df_orig.copy()
method1( df ) # df appears to be view of global df, no need to return it
df1 = df
答案 1 :(得分:1)
这并不是你想要的,而是另一条思考的道路。
有一个要点here定义了一个上下文管理器,它允许您引用列,就像它们是本地人一样。我没有写这个,它有点旧,但似乎仍然适用于当前版本的熊猫。
In [45]: df = pd.DataFrame({'x': np.random.randn(100000), 'y': np.random.randn(100000)})
In [46]: with DataFrameContextManager(df):
...: z = x + y
...:
In [47]: z.head()
Out[47]:
0 -0.821079
1 0.035018
2 1.180576
3 -0.155916
4 -2.253515
dtype: float64