我正在为以下问题寻找更优雅和Pythonic的代码:
在开始列中,每个项目都有一个发布周(从1到4),我添加了 W1,...,W4 列。
接下来我想以这种方式更新列(基本上,用零替换发布周和前一周和后一周的列):
start W1 W2 W3 W4
1 0 0 1 1
2 0 0 0 1
3 1 0 0 0
4 1 1 0 0
我现在就这样做:
import pandas as pd
data = {'start': [1,2,3,4]}
df = pd.DataFrame(data)
for i in range(1,4+1):
df['W'+str(i)] = 1
for index, i in enumerate(df['start']):
if i==1:
df.ix[index, 'W1'] = 0
df.ix[index, 'W2'] = 0
elif i==4:
df.ix[index, 'W3'] = 0
df.ix[index, 'W4'] = 0
else:
df.ix[index, 'W'+str(i-1)] = 0
df.ix[index, 'W'+str(i)] = 0
df.ix[index, 'W'+str(i+1)] = 0
答案 0 :(得分:1)
执行广播numpy比较以获取掩码,并将相应索引处的值设置为0
。
df.set_index('start', inplace=True)
i = df.index.values
j = np.arange(1, len(df) + 1)[:, None]
df.values[(i - 1 <= j) & (j <= i + 1)] = 0
df
W1 W2 W3 W4
start
1 0 0 1 1
2 0 0 0 1
3 1 0 0 0
4 1 1 0 0
<强>详情
i
array([1, 2, 3, 4])
j
array([[1],
[2],
[3],
[4]])
首先,计算面具 -
m = (i - 1 <= j) & (j <= i + 1)
m
array([[ True, True, False, False],
[ True, True, True, False],
[False, True, True, True],
[False, False, True, True]], dtype=bool)
掩码m
适用于整个数据帧。只需在values
上编制索引,然后将单元格设置为0
-
df.values[m] = 0
要重置索引,请使用reset_index
-
df.reset_index()
start W1 W2 W3 W4
0 1 0 0 1 1
1 2 0 0 0 1
2 3 1 0 0 0
3 4 1 1 0 0
答案 1 :(得分:1)
从你的df
df = df.astype(int)
start W1 W2 W3 W4
0 1 1 1 1 1
1 2 1 1 1 1
2 3 1 1 1 1
3 4 1 1 1 1
您可以使用以下函数将map应用于df以重新计算值:
def func(pivot):
return [1 if abs(col-pivot) > 1 else 0 for col in [1,2,3,4]]
这是我的第一个地图选项,不必要的复杂:
df['W1'], df['W2'], df['W3'], df['W4'] = zip(*df['start'].map(func))
这个来自@QuantChristo,好多了
weeks = ['W1','W2','W3','W4']
df[weeks] = df['start'].map(func)
在这两种情况下你都得到df:
start W1 W2 W3 W4
0 1 0 0 1 1
1 2 0 0 0 1
2 3 1 0 0 0
3 4 1 1 0 0