Python 3.x 如何使用np.where/np.select根据某些条件更新数据框列中的各个词典?

Python 3.x 如何使用np.where/np.select根据某些条件更新数据框列中的各个词典?,python-3.x,pandas,numpy,Python 3.x,Pandas,Numpy,我有一个熊猫数据帧df,如下所示 id Surname DOB X1 Y1 TRACEID 0 1 Garud 2019-01-01T12:10 xxx yyyy {} 1 2 Garud 2019-01-01T12:10 xxx yyyy {} 2 3 Garud 2019-01-02T12:10 xxx yyyy {}

我有一个熊猫数据帧df,如下所示

    id Surname   DOB                X1   Y1     TRACEID
0   1   Garud   2019-01-01T12:10    xxx yyyy    {}         
1   2   Garud   2019-01-01T12:10    xxx yyyy    {}            
2   3   Garud   2019-01-02T12:10    xxx yyyy    {}            
3   4   Kadam   2019-01-06T12:10    xxx yyyy    {}            
4   5   Kadam   2019-01-03T12:10    xxx yyyy    {}            
5   6   Kadam   2019-01-04T12:10    xxx yyyy    {}              
TRACEID列包含空字典: 我想根据X1和Y1列填写这些词典

  • 如果X1和Y1列值均为非空,则相应的TRACEID应为{'X1':'xxx','Y1':'yyyy'}
  • 如果Y1列值为null,则TRACEID将为{'X1':'xxxx'}
  • 如果X1列值为null,则TRACEID将为{'Y1':'yyyy'}
我试着用下面的方法

list1 = ['X1','Y1']
for col in list1:
    df['TRACEID'] = np.where(df[col]!='',df['TRACEID'].update({col:df[col]}),df['TRACEID'])
但是,这将在TRACEID列中指定所有None值


我知道,我可以使用
df.iterrows()
,但我不想这样做,因为迭代需要很多时间。df有大约10万条记录。因此必须使用
np来实现。选择
np。其中

您的
df['TRACEID']中的问题。更新({col:df[col]})
是指您使用不当和
dict.update()
。这是两种不同的方法。你能行

#确保'TRACEID'列是dict
df['TRACEID']=[dict()表示范围内的uuu(len(df['TRACEID'])]
def更新目录(世界其他地区):
#复制原始dict,因为dict.update已就位,
#它将影响'df['TRACEID']中的原始on`
复制=行['TRACEID']。复制()
复制的.update({col:df.loc[row.name,col]})
返回副本
对于列表1中的列:
df['TRACEID']=np.where(df[col]!='',df.apply(update_dict,axis=1),df['TRACEID']))
此外,在适当的位置修改系列。所以你不能这么做

对于列表1中的列:
res=[]
对于zip中的i,v(df.index,df['TRACEID']):
复制的,复制的
复制的.update({col:df.loc[i,col]})
res.append(已复制)
df['TRACEID']=np.where(df[col]!='',df['TRACEID'].update(pd.Series(res)),df['TRACEID']))
您可以直接使用
apply()
<代码>轴=1
表示行上的功能

def更新(行):
traceid=dict()
对于['X1','Y1']中的列:
如果行[col]!='':
traceid[col]=行[col]
返回轨迹ID
df['TRACEID']=df.apply(更新,轴=1)

另一种策略是通过
.to_dict()
生成完整的
dict
s,然后清理dict。这并不意味着比单一步骤应用更容易,但可以为操作输出字典提供灵活性

资料 解决方案 结果
当同一行中的两列都为null时会发生什么情况?使用
apply()
,这非常简单,您想要这个答案吗?@Umar.H-在我的情况下,这是不可能的。这两列中的任何一列都将始终有值。@Ynjxsjmh-请选择“是”,这将非常有用。
n'p.where
不是迭代器。这3个参数在传递给它之前会进行完整的计算。分别查看它们,并告诉我们这些值是否合理。DICT是独立的对象(或者可能是同一个对象),必须单独更新。这是可行的,但正如我所说的,对于larfe dataframe>10万行,这将消耗太多的时间,因为它逐行执行。需要使用numpy.where或numpy.select加快执行。任何使用这些答案的人都将不胜感激。谢谢。知道为什么我的解决方案不起作用吗?list1=['X1','Y1']表示列表1中的列:df['TRACEID']=np.where(df[col]!='',df['TRACEID'])。更新({col:df[col]}),df['TRACEID'])
df[col!=''看起来不对。你是说
~df[col].isna()
# print(df)

   id Surname               DOB   X1    Y1                      TRACEID
0   1   Garud  2019-01-01T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
1   2   Garud  2019-01-01T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
2   3   Garud  2019-01-02T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
3   4   Kadam  2019-01-06T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
4   5   Kadam  2019-01-03T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
5   6   Kadam  2019-01-04T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}
import pandas as pd
import io

df = pd.read_csv(io.StringIO("""
    id Surname   DOB                X1    Y1     TRACEID
0   1   Garud   2019-01-01T12:10    nan  yyyy    {}         
1   2   Garud   2019-01-01T12:10    xxx   nan    {}            
2   3   Garud   2019-01-02T12:10    nan   nan    {}            
3   4   Kadam   2019-01-06T12:10    xxx  yyyy    {}            
"""), sep=r"\s{2,}", engine='python')
# get the full dict directly
df["TRACEID"] = df[["X1", "Y1"]].to_dict(orient="records")
# clean up the dict
df["TRACEID"] = df["TRACEID"].apply(lambda dic: {k: v for k, v in dic.items() if not pd.isna(v)})
print(df)

    id Surname               DOB   X1    Y1                      TRACEID
0 1      Garud  2019-01-01T12:10  NaN  yyyy               {'Y1': 'yyyy'}
1 2      Garud  2019-01-01T12:10  xxx   NaN                {'X1': 'xxx'}
2 3      Garud  2019-01-02T12:10  NaN   NaN                           {}
3 4      Kadam  2019-01-06T12:10  xxx  yyyy  {'X1': 'xxx', 'Y1': 'yyyy'}