我有以下数据框:
> df = pd.DataFrame({'A':[1,1,1,1,0],'B':[1,0,1,1,0],'C':[1,1,1,0,0],'D':[1,1,0,0,0],'E':[1,0,0,0,0]})
> print(df)
A B C D E
0 1 1 1 1 1
1 1 0 1 1 0
2 1 1 1 0 0
3 1 1 0 0 0
4 0 0 0 0 0
我想产生一个具有相同列的新数据框,该列将执行以下操作:
如果该行左侧的所有单元格均等于1,则将每个单元格置于1,否则置0。
因此,给定示例的输出应如下所示:
> df = pd.DataFrame({'A':[1,1,1,1,0],'B':[1,0,1,1,0],'C':[1,0,1,0,0],'D':[1,0,0,0,0],'E':[1,0,0,0,0]})
> print(df)
A B C D E
0 1 1 1 1 1
1 1 0 0 0 0
2 1 1 1 0 0
3 1 1 0 0 0
4 0 0 0 0 0
我正在寻找一种通用代码,该代码可以在所有大小的所有数据帧中复制。
我做了一个google搜索,并尝试自己编写代码,但是没有得到令人满意的结果。
另一个例子-行级的转换看起来像这样:
1,1,1,0,1,1,0,0,1-> 1,1,1,0,0,0,0,0,0,
谢谢!
答案 0 :(得分:1)
您可以定义一个简单的函数来查找第一个出现0的索引,然后将填充了1的数组返回到该位置。还需要考虑不包含零的行,然后将其全部发送回1。
def findOnes(x):
res = np.zeros(len(x))
fstZero = np.where(x==0)[0]
if len(fstZero) == 0:
return res+1
return res[:np.min(fstZero)]=1
然后可以将此功能应用于原始的dataframe
。
dfNew = df.apply(findOnes, axis=1, result_type='broadcast')
这将给出所需的输出:
print(dfNew)
A B C D E
0 1 1 1 1 1
1 1 0 0 0 0
2 1 1 1 0 0
3 1 1 0 0 0
4 0 0 0 0 0
因此,使用完整解决方案上方的数据看起来像
import pandas as pd
import numpy as np
def findOnes(x):
res = np.zeros(len(x))
fstZero = np.where(x==0)[0]
if len(fstZero) == 0:
return res+1
return res[:np.min(fstZero)]=1
df = pd.DataFrame({'A':[1,1,1,1,0],'B':[1,0,1,1,0],'C':[1,1,1,0,0],
'D':[1,1,0,0,0],'E':[1,0,0,0,0]})
dfNew = df.apply(findOnes, axis=1, result_type='broadcast')
答案 1 :(得分:0)
对于大型DataFrame来说,这可能不是最有效的方法,但可以解决任意大小的问题。
import pandas as pd
df = pd.DataFrame({'A':[1,1,1,1,0],'B':[1,0,1,1,0],'C':[1,1,1,0,0],'D':[1,1,0,0,0],'E':[1,0,0,0,0]})
output = []
for i in range(df.shape[0]):
o = [1 for j in range(df.shape[1]) if all(df.iloc[i, :j+1] == 1)]
output.append(o)
# Convert output to a DataFrame
output = pd.DataFrame(output, columns=df.columns)
output.fillna(0, inplace=True)
检查输出
print(output)
A B C D E
0 1.0 1.0 1.0 1.0 1.0
1 1.0 0.0 0.0 0.0 0.0
2 1.0 1.0 1.0 0.0 0.0
3 1.0 1.0 0.0 0.0 0.0
4 0.0 0.0 0.0 0.0 0.0