簡體   English   中英

如何在 pandas dataframe 中為具有字符串條件的新列分配值

[英]How to assign a value to a new column with a string condition in pandas dataframe

如果第一列包含某個字母,我嘗試根據條件為數據框中的新列分配值。 如果第一列只包含一個字母,我使用虛擬變量 function。 但是,如果第一列包含數字、字符串和 Nan 呢?

這是一個例子:

# Before
   c1
0   a
1   2
2   b
3   c
4   ab
5   bc
6   NaN

#After
    c1  a   b   c
0   a   1   0   0
1   2   0   0   0
2   b   0   1   0
3   c   0   0   1
4   ab  1   1   0
5   bc  0   1   1
6   NaN 0   0   0

我嘗試str.contains()進行分配,但出現錯誤:

x['a'] = 1 if x.c1.str.contains('a') else 0

The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

可以這樣做:

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,並且其中包含適當的字符。

對於您的問題,您可以使用 pandas.get_dummies() function ,它將分類變量轉換為指標

  1. 然后將您的 dataframe 轉換為列表(可選)
  2. 然后使用以下代碼創建分類虛擬變量:
    lst = ['a', 2, 'b', 'c', 'ab', np.nan]

    pd.get_dummies(lst).T
  1. 比較並合並虛擬標識符以獲得所需的結果

您可以通過多種方式做到這一點,您的主要問題之一是您的列不是字符串,您可以這樣做:

df = pd.DataFrame([{"c1": "a"}, {"c1":2}])
df["new_column"] = 0
df["new_column"][df["c1"].astype(str).str.contains('a')] = 1

或者

def custom_funct(row):
    print(row)
    if "a" in str(row["c1"]):
        row["new_column"] = 1
    else:
        row["new_column"] = 0
    return row


df = pd.DataFrame([{"c1": "a"}, {"c1":2}])
df["new_column"] = None
df = df.apply(custom_funct,axis=1)
df
    c1
0   a
1   2
2   b
3   c
4   ab
5   bc
6   NaN

首先,您可以將NaN替換為一些虛擬字符(例如 #),因為這樣會更容易處理字符串。 然后您可以apply list應用於整個列,以便分別獲取每個字符。 此后,您可以使用explode將每行中的每個字符分成多行。 轉換為 dataframe 並添加一列,以便可以創建 pivot 表。

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

然后您可以創建以c1作為列和以 1s 作為值的列的pivot_table表。 之后,您可以只保留字母列。 最后,將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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM