Python 如何在dataframe中使用字符串条件为新列赋值

Python 如何在dataframe中使用字符串条件为新列赋值,python,pandas,dataframe,Python,Pandas,Dataframe,我尝试根据条件为数据框中的一个新列赋值,如果第一列是否包含某个字母。如果第一列只包含一个字母,我使用虚拟变量函数。但是,如果第一列包含数字、字符串和Nan,又如何呢 以下是一个例子: #之前 c1 0 a 1 2 2 b 3 c 4 ab 公元前5年 6南 #之后 c1 a b c 0 a 10 0 0 1 2 0 0 0 2B010 3C001 4 ab 11 0 公元前5年01月1日 6南0 0 我尝试str.contains()分配,但出现错误: x['a']=1,如

我尝试根据条件为数据框中的一个新列赋值,如果第一列是否包含某个字母。如果第一列只包含一个字母,我使用虚拟变量函数。但是,如果第一列包含数字、字符串和Nan,又如何呢

以下是一个例子:

#之前
c1
0 a
1   2
2 b
3 c
4 ab
公元前5年
6南
#之后
c1 a b c
0 a 10 0 0
1   2   0   0   0
2B010
3C001
4 ab 11 0
公元前5年01月1日
6南0 0
我尝试
str.contains()
分配,但出现错误:

x['a']=1,如果x.c1.str.contains('a'),否则为0
级数的真值是模糊的。使用a.empty、a.bool()、a.item()、a.any()或a.all()。

对于您的问题,您可以使用pandas.get_dummies(),它将分类变量转换为指示符

  • 然后将数据帧转换为列表(可选)
  • 然后使用以下代码创建分类伪变量:
  • 比较并合并所需结果的虚拟标识符
  • 你可以这样做:

    df['a'] = df['c1'].str.contains('a').astype(int)
    
    。。。但是,如果在
    df['c1']
    中有任何
    NaN
    值,则会引发
    ValueError
    (就像您在示例中所做的那样)

    这里有一个使用df.apply的替代方法:

    df['a'] = df['c1'].apply(lambda x: int('a' in x) if isinstance(x, str) else 0)
    

    此方法还处理由多种类型组成的列:仅当给定的行是字符串时,它才会返回1,此外还包含适当的字符。

    您可以通过多种方式执行此操作。您的主要问题之一是,您的列不是字符串,您可以像这样执行:

    df=pd.DataFrame([{“c1”:“a”},{“c1”:2}])
    df[“新_列”]=0
    df[“新列”][df[“c1”].astype(str).str.contains('a')]=1
    

    def自定义函数(行):
    打印(行)
    如果str(第[“c1”行]中的“a”):
    行[“新列”]=1
    其他:
    行[“新列”]=0
    返回行
    df=pd.DataFrame([{“c1”:“a”},{“c1”:2}])
    df[“新列”]=无
    df=df.apply(自定义函数,轴=1)
    
    首先,您可以用一些伪字符(比如#)替换
    NaN
    s,因为这样更容易处理字符串。然后,您可以将
    列表
    应用于整个列,以便分别获取每个字符。此后,可以使用
    分解
    将每行中的每个字符分隔为多行。转换为dataframe并添加一列数据帧,以便可以创建透视表

    temp = df['c1'].fillna('#').apply(list).explode().to_frame().reset_index()
    temp['vals'] = 1
    temp
      index c1  vals
    0   0   a   1
    1   1   2   1
    2   2   b   1
    3   3   c   1
    4   4   a   1
    5   4   b   1
    6   5   b   1
    7   5   c   1
    8   6   #   1
    
    然后,您可以创建
    pivot_表
    ,其中
    c1
    为列,1s为值的列。之后,您可以只保留字母表中的列。最后,将
    temp
    表与原始df合并

    temp = pd.pivot_table(temp, columns='c1', index="index", values='vals')
    cols_retain = [c for c in temp.columns if re.search(r'[A-Za-z]', c)]
    pd.concat([df, temp[cols_retain].fillna(0)], axis=1)
        c1  a   b   c
    0   a   1.0 0.0 0.0
    1   2   0.0 0.0 0.0
    2   b   0.0 1.0 0.0
    3   c   0.0 0.0 1.0
    4   ab  1.0 1.0 0.0
    5   bc  0.0 1.0 1.0
    6   NaN 0.0 0.0 0.0
    

    谢谢你的发帖!它起作用了@Carlos thank you注释是不必要的,如果答案有帮助,您应该投票并/或接受它作为正确的解决方案。
    temp = df['c1'].fillna('#').apply(list).explode().to_frame().reset_index()
    temp['vals'] = 1
    temp
      index c1  vals
    0   0   a   1
    1   1   2   1
    2   2   b   1
    3   3   c   1
    4   4   a   1
    5   4   b   1
    6   5   b   1
    7   5   c   1
    8   6   #   1
    
    temp = pd.pivot_table(temp, columns='c1', index="index", values='vals')
    cols_retain = [c for c in temp.columns if re.search(r'[A-Za-z]', c)]
    pd.concat([df, temp[cols_retain].fillna(0)], axis=1)
        c1  a   b   c
    0   a   1.0 0.0 0.0
    1   2   0.0 0.0 0.0
    2   b   0.0 1.0 0.0
    3   c   0.0 0.0 1.0
    4   ab  1.0 1.0 0.0
    5   bc  0.0 1.0 1.0
    6   NaN 0.0 0.0 0.0