Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 新列的条件生成_Python_Pandas_Conditional Statements - Fatal编程技术网

Python 新列的条件生成

Python 新列的条件生成,python,pandas,conditional-statements,Python,Pandas,Conditional Statements,我正在尝试基于预先存在的列上的条件逻辑创建一个新列。我知道可能有更有效的方法来实现这一点,但我有一些条件需要包括在内。这只是第一步 总体范围是创建从1和2映射的两个新列。它们被引用到对象列,因为我可以为每个时间点创建多行 Object2和Value确定如何映射新列。因此,如果Value==X,我想匹配Object列,将该时间点对应的1和2返回到一个新列。如果值为==Y,则应发生相同的过程。如果值为==Z,我想插入0,0。其他所有内容都应该是NaN df = pd.DataFrame({

我正在尝试基于预先存在的列上的条件逻辑创建一个新列。我知道可能有更有效的方法来实现这一点,但我有一些条件需要包括在内。这只是第一步

总体范围是创建从
1
2
映射的两个新列。它们被引用到
对象
列,因为我可以为每个时间点创建多行

Object2
Value
确定如何映射新列。因此,如果
Value==X
,我想匹配
Object
列,将该时间点对应的
1
2
返回到一个新列。如果
值为==Y
,则应发生相同的过程。如果
值为==Z
,我想插入
0,0
。其他所有内容都应该是
NaN

df = pd.DataFrame({   
        'Time' : ['2019-08-02 09:50:10.1','2019-08-02 09:50:10.1','2019-08-02 09:50:10.2','2019-08-02 09:50:10.3','2019-08-02 09:50:10.3','2019-08-02 09:50:10.4','2019-08-02 09:50:10.5','2019-08-02 09:50:10.6','2019-08-02 09:50:10.6'],
        'Object' : ['B','A','A','A','C','C','C','B','B'],
        '1' : [1,3,5,7,9,11,13,15,17],  
        '2' : [0,1,4,6,8,10,12,14,16],     
        'Object2' : ['A','A',np.nan,'C','C','C','C','B','A'],                 
        'Value' : ['X','X',np.nan,'Y','Y','Y','Y','Z',np.nan],                  
        })

def map_12(df):

for i in df['Value']:
    if i == 'X':
        df['A1'] = df['1']
        df['A2'] = df['2']
    elif i == 'Y':
        df['A1'] = df['1']
        df['A2'] = df['2']     
    elif i == 'Z':
        df['A1'] = 0
        df['A2'] = 0             
    else:
        df['A1'] = np.nan
        df['A2'] = np.nan              

return df
预期产出:

                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      A   1   0       A     X   1.0   0.0 # Match A-A at this time point, so output is 1,0
1  2019-08-02 09:50:10.1      B   3   1       A     X   1.0   0.0 # Still at same time point so use 1,0 
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN # No Value so NaN
3  2019-08-02 09:50:10.3      C   7   6       C     Y   7.0   6.0 # Match C-C at this time point, so output is 7,6
4  2019-08-02 09:50:10.3      A   9   8       C     Y   7.0   6.0 # Still at same time point so use 7,6 
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0 # Match C-C at this time point, so output is 11,10
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0 # Match C-C at this time point, so output is 13,12
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0 # Z so 0,0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN # No Value so NaN
                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      B   1   0       A     X   3.0   1.0 # Match A-A at this time point, so output is 3,1
1  2019-08-02 09:50:10.1      A   3   1       A     X   3.0   1.0 # Still at same time point so use 3,1 
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN # No Value so NaN
3  2019-08-02 09:50:10.3      A   7   6       C     Y   9.0   8.0 # Match C-C at this time point, so output is 9,8
4  2019-08-02 09:50:10.3      C   9   8       C     Y   9.0   8.0 # Still at same time point so use 9,8 
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0 # Match C-C at this time point, so output is 11,10
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0 # Match C-C at this time point, so output is 13,12
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0 # Z so 0,0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN # No Value so NaN
新样本df:

 df = pd.DataFrame({   
        'Time' : ['2019-08-02 09:50:10.1','2019-08-02 09:50:10.1','2019-08-02 09:50:10.2','2019-08-02 09:50:10.3','2019-08-02 09:50:10.3','2019-08-02 09:50:10.4','2019-08-02 09:50:10.5','2019-08-02 09:50:10.6','2019-08-02 09:50:10.6'],
        'Object' : ['B','A','A','A','C','C','C','B','B'],
        '1' : [1,3,5,7,9,11,13,15,17],  
        '2' : [0,1,4,6,8,10,12,14,16],     
        'Object2' : ['A','A',np.nan,'C','C','C','C','B','A'],                 
        'Value' : ['X','X',np.nan,'Y','Y','Y','Y','Z',np.nan],                
        })
预期产出:

                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      A   1   0       A     X   1.0   0.0 # Match A-A at this time point, so output is 1,0
1  2019-08-02 09:50:10.1      B   3   1       A     X   1.0   0.0 # Still at same time point so use 1,0 
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN # No Value so NaN
3  2019-08-02 09:50:10.3      C   7   6       C     Y   7.0   6.0 # Match C-C at this time point, so output is 7,6
4  2019-08-02 09:50:10.3      A   9   8       C     Y   7.0   6.0 # Still at same time point so use 7,6 
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0 # Match C-C at this time point, so output is 11,10
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0 # Match C-C at this time point, so output is 13,12
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0 # Z so 0,0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN # No Value so NaN
                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      B   1   0       A     X   3.0   1.0 # Match A-A at this time point, so output is 3,1
1  2019-08-02 09:50:10.1      A   3   1       A     X   3.0   1.0 # Still at same time point so use 3,1 
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN # No Value so NaN
3  2019-08-02 09:50:10.3      A   7   6       C     Y   9.0   8.0 # Match C-C at this time point, so output is 9,8
4  2019-08-02 09:50:10.3      C   9   8       C     Y   9.0   8.0 # Still at same time point so use 9,8 
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0 # Match C-C at this time point, so output is 11,10
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0 # Match C-C at this time point, so output is 13,12
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0 # Z so 0,0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN # No Value so NaN
看看


我不得不对您的数据帧进行一些调整,因为它与您问题中的预期结果不匹配

df = pd.DataFrame(
    {
        "Time": [
            "2019-08-02 09:50:10.1",
            "2019-08-02 09:50:10.1",
            "2019-08-02 09:50:10.2",
            "2019-08-02 09:50:10.3",
            "2019-08-02 09:50:10.3",
            "2019-08-02 09:50:10.4",
            "2019-08-02 09:50:10.5",
            "2019-08-02 09:50:10.6",
            "2019-08-02 09:50:10.6",
        ],
        "Object": ["A", "B", "A", "C", "A", "C", "C", "B", "B"],
        "1": [1, 1, 5, 7, 9, 11, 13, 15, 17],
        "2": [0, 1, 4, 6, 8, 10, 12, 14, 16],
        "Object2": ["A", "A", np.nan, "C", "C", "C", "C", "B", "A"],
        "Value": ["X", "X", np.nan, "Y", "Y", "Y", "Y", "Z", np.nan],
    }
)
这是一个矢量化的解决方案,应该在大数据上运行良好

第一步是确保数据帧按时间排序

df = df.sort_values("Time")
复制第1列和第2列

df["A1"] = df["1"]
df["A2"] = df["2"]
将使用索引值获取每个时间组的第一行

df = df.reset_index()
我对列表/isin解决方案不太满意。好奇是否有人知道一种不那么老套的方法

li = df.groupby("Time").index.first().tolist()

print(li)
[0, 2, 3, 5, 6, 7]

print(df)
   index                   Time Object   1   2 Object2 Value  A1  A2
0      0  2019-08-02 09:50:10.1      A   1   0       A     X   1   0
1      1  2019-08-02 09:50:10.1      B   1   1       A     X   1   1
2      2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   5   4
3      3  2019-08-02 09:50:10.3      C   7   6       C     Y   7   6
4      4  2019-08-02 09:50:10.3      A   9   8       C     Y   9   8
5      5  2019-08-02 09:50:10.4      C  11  10       C     Y  11  10
6      6  2019-08-02 09:50:10.5      C  13  12       C     Y  13  12
7      7  2019-08-02 09:50:10.6      B  15  14       B     Z  15  14
8      8  2019-08-02 09:50:10.6      B  17  16       A   NaN  17  16
过滤数据帧以获取除列表中的行以外的所有行,然后将它们设置为np.NaN

df.loc[~df.index.isin(li), ["A1", "A2"]] = np.NaN
df.loc[df["Value"] == "Z", ["A1", "A2"]] = 0
df.loc[df["Value"].isnull(), ["A1", "A2"]] = np.NaN
向前填充第一行值

df[["A1", "A2"]] = df[["A1", "A2"]].ffill(axis=0)
将z设置为0,将np.NaN设置为np.NaN

df.loc[~df.index.isin(li), ["A1", "A2"]] = np.NaN
df.loc[df["Value"] == "Z", ["A1", "A2"]] = 0
df.loc[df["Value"].isnull(), ["A1", "A2"]] = np.NaN
删除索引列

df = df.drop("index", axis=1)

print(df)
                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      A   1   0       A     X   1.0   0.0
1  2019-08-02 09:50:10.1      B   1   1       A     X   1.0   0.0
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN
3  2019-08-02 09:50:10.3      C   7   6       C     Y   7.0   6.0
4  2019-08-02 09:50:10.3      A   9   8       C     Y   7.0   6.0
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN
使用+创建类似于
df[['1','2']]
但仅适用于匹配为
True
的行,其余为
NaN
。 然后使用时间点分组,并用现有值填充每组缺失的数据​​其中
Object
Object2
匹配==True
)重合。用于在
df['Value']
NaN
的位置分解值。最后,当
Z
位于
Value
列中时,使用[
DataFrame.mask
]设置0

#matches
matches=df.Object.eq(df.Object2)
#Creating conditions
condition_z=df['Value']=='Z'
not_null=df['Value'].notnull()
#Creating DataFrame to fill
df12=( df[['1','2']].where(matches)
                    .groupby(df['Time'],sort=False)
                    .apply(lambda x: x.ffill().bfill()) )
#fill 0 on Value is Z and discarting NaN
df[['A1','A2']] =df12.where(not_null).mask(condition_z,0)
print(df)
输出

                    Time Object   1   2 Object2 Value    A1    A2
0  2019-08-02 09:50:10.1      B   1   0       A     X   3.0   1.0
1  2019-08-02 09:50:10.1      A   3   1       A     X   3.0   1.0
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN   NaN   NaN
3  2019-08-02 09:50:10.3      A   7   6       C     Y   9.0   8.0
4  2019-08-02 09:50:10.3      C   9   8       C     Y   9.0   8.0
5  2019-08-02 09:50:10.4      C  11  10       C     Y  11.0  10.0
6  2019-08-02 09:50:10.5      C  13  12       C     Y  13.0  12.0
7  2019-08-02 09:50:10.6      B  15  14       B     Z   0.0   0.0
8  2019-08-02 09:50:10.6      B  17  16       A   NaN   NaN   NaN

我们还可以使用:


如果只有少数条件用于按条件赋值:

m1 = df['Value'].isin(['X','Y'])
m2 = df['Value'] == 'Z'

df[['A1','A2']] = df.loc[m1, ['1','2']]
df.loc[m2, ['A1','A2']] = 0
print(df)
                    Time Object   1   2 Object2 Value   A1   A2
0  2019-08-02 09:50:10.1      A   1   0       A     X  1.0  0.0
1  2019-08-02 09:50:10.1      B   1   1       A     X  1.0  1.0
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN  NaN  NaN
3  2019-08-02 09:50:10.3      C   7   6       C     Y  7.0  6.0
4  2019-08-02 09:50:10.3      A   9   8       C     Y  9.0  8.0
5  2019-08-02 09:50:10.4      C  11  10     NaN   NaN  NaN  NaN
6  2019-08-02 09:50:10.5      C  13  12       B   NaN  NaN  NaN
7  2019-08-02 09:50:10.6      B  15  14       B     Z  0.0  0.0
8  2019-08-02 09:50:10.6      B  17  16       B   NaN  NaN  NaN
另一个解决方案是使用和播放遮罩:

m1 = df['Value'].isin(['X','Y'])
m2 = df['Value'] == 'Z'

masks = [m1.values[:, None], m2.values[:, None]]
values = [df[['1','2']].values, 0]

df[['A1','A2']] = pd.DataFrame(np.select(masks,values, default=np.nan), index=df.index)
print(df)
                    Time Object   1   2 Object2 Value   A1   A2
0  2019-08-02 09:50:10.1      A   1   0       A     X  1.0  0.0
1  2019-08-02 09:50:10.1      B   1   1       A     X  1.0  1.0
2  2019-08-02 09:50:10.2      A   5   4     NaN   NaN  NaN  NaN
3  2019-08-02 09:50:10.3      C   7   6       C     Y  7.0  6.0
4  2019-08-02 09:50:10.3      A   9   8       C     Y  9.0  8.0
5  2019-08-02 09:50:10.4      C  11  10     NaN   NaN  NaN  NaN
6  2019-08-02 09:50:10.5      C  13  12       B   NaN  NaN  NaN
7  2019-08-02 09:50:10.6      B  15  14       B     Z  0.0  0.0
8  2019-08-02 09:50:10.6      B  17  16       B   NaN  NaN  NaN

你有什么问题?这是最接近的,而不是
df['A1']=df['1']
df['A1']=1谢谢@run out。我认为我们需要包含对
对象
列的引用。仅当先列出参考值时,此选项才有效。我将添加一个新的示例df以显示错误。在有多个条目的情况下,我如何确定应该使用哪个“参考值”?谢谢@jezrael,这比这个稍微复杂一点。我已经对我的预期输出添加了评论,并添加了一个新的示例df来突出这一点。感谢@ansev在这里的努力,但我的预期输出稍微复杂一些。我已经添加了强调逻辑的注释。感谢您澄清。更新了我的解决方案的所有方法。请检查:)谢谢ansev,但我的预期输出有点不同。我需要为每个时间点匹配
Object
列,并填充到下一个时间点。这有意义吗。我的预期输出已经为每一行添加了注释。请注意,Object和Object2之间的等价性是按时间分组的,并使用transform(“any”)进行扩展。请查看我的预期输出。索引1和索引4位于同一时间点,因此我仍然希望使用前几行中匹配的数字。