从列中获取字符串的第一个字母

我正在和熊猫战斗,现在我正在失败。我有一个类似的源表:

import pandas as pd


a=pd.Series([123,22,32,453,45,453,56])
b=pd.Series([234,4353,355,453,345,453,56])
df=pd.concat([a, b], axis=1)
df.columns=['First', 'Second']

我想在这个数据框中添加新的列,第一个数字来自列‘ First’中的值: A)将数字由‘ First’列改为字符串 B)从新创建的字符串中提取第一个字符 C)将 b 的结果另存为数据框中的新列

我不知道如何将其应用到熊猫数据帧对象。我会很感激你的帮助。

175595 次浏览

将 coll 的 dtype转换为 str,就可以执行向量切片调用 str:

In [29]:
df['new_col'] = df['First'].astype(str).str[0]
df


Out[29]:
First  Second new_col
0    123     234       1
1     22    4353       2
2     32     355       3
3    453     453       4
4     45     345       4
5    453     453       4
6     56      56       5

如果你需要,你可以把 dtype再次调用 astype(int)的列

.str.get

这是指定字符串方法最简单的方法

# Setup
df = pd.DataFrame({'A': ['xyz', 'abc', 'foobar'], 'B': [123, 456, 789]})
df


A    B
0     xyz  123
1     abc  456
2  foobar  789


df.dtypes


A    object
B     int64
dtype: object

对于 string (read: object)类型的列,使用

df['C'] = df['A'].str[0]
# Similar to,
df['C'] = df['A'].str.get(0)

.str通过返回 NaN 作为输出来处理 NaN。

对于非数字列,需要事先进行 .astype转换,如@Ed Chum 的答案所示。

# Note that this won't work well if the data has NaNs.
# It'll return lowercase "n"
df['D'] = df['B'].astype(str).str[0]

df
A    B  C  D
0     xyz  123  x  1
1     abc  456  a  4
2  foobar  789  f  7

列表内涵和索引

有一个 足够的证据建议一个简单的列表内涵将在这里工作得很好,可能更快。

# For string columns
df['C'] = [x[0] for x in df['A']]


# For numeric columns
df['D'] = [str(x)[0] for x in df['B']]

df
A    B  C  D
0     xyz  123  x  1
1     abc  456  a  4
2  foobar  789  f  7

如果你的数据有 NaN,那么你需要在列表内涵中使用一个 if/else来适当地处理这个问题,

df2 = pd.DataFrame({'A': ['xyz', np.nan, 'foobar'], 'B': [123, 456, np.nan]})
df2


A      B
0     xyz  123.0
1     NaN  456.0
2  foobar    NaN


# For string columns
df2['C'] = [x[0] if isinstance(x, str) else np.nan for x in df2['A']]


# For numeric columns
df2['D'] = [str(x)[0] if pd.notna(x) else np.nan for x in df2['B']]


A      B    C    D
0     xyz  123.0    x    1
1     NaN  456.0  NaN    4
2  foobar    NaN    f  NaN

让我们对更大的数据做一些时间测试。

df_ = df.copy()
df = pd.concat([df_] * 5000, ignore_index=True)


%timeit df.assign(C=df['A'].str[0])
%timeit df.assign(D=df['B'].astype(str).str[0])


%timeit df.assign(C=[x[0] for x in df['A']])
%timeit df.assign(D=[str(x)[0] for x in df['B']])

12 ms ± 253 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
27.1 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)


3.77 ms ± 110 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
7.84 ms ± 145 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

列表理解要快4倍。