从另一列列表中的特定值填充一个 Dataframe 列
Fill one Dataframe Column from specific value in list of another column
我的数据框有一个包含密钥对 list
的列 pairs
。每个键在列表中都是唯一的。例如:
df = pd.DataFrame({
'id': ['1', '2', '3'],
'abc':None,
'pairs': [ ['abc/123', 'foo/345', 'xyz/789'], ['abc/456', 'foo/111', 'xyz/789'], ['xxx/222', 'foo/555', 'xyz/333'] ]
})
数据帧是:
id | abc | pairs
------------------------------------
1 |None | [abc/123, foo/345, xyz/789]
2 |None | [abc/456, foo/111, xyz/789]
3 |None | [xxx/222, foo/555, xyz/333]
如果被 \
拆分的元素 (idx=0) 具有值 (key) ==[=39,则 abc
列将填充 pairs
列中的值=].
预期 df
:
id | abc | pairs
------------------------------------
1 |123 | [abc/123, foo/345, xyz/789]
2 |456 | [abc/456, foo/111, xyz/789]
3 |None | [xxx/222, foo/555, xyz/333]
我在寻找类似的东西:
df.loc[df['pairs'].map(lambda x: 'abc' in (l.split('/')[0] for l in x)), 'abc'] = 'FOUND'
我的问题是用 l.split('/')[0]
的正确值替换 FOUND
您可以重复使用.str
:
df['abc'] = df['pairs'].str[0].str.split('/').loc[lambda x: x.str[0] == 'abc'].str[1]
输出:
>>> df
id abc pairs
0 1 123 [abc/123, foo/345, xyz/789]
1 2 456 [abc/456, foo/111, xyz/789]
2 3 NaN [xxx/222, foo/555, xyz/333]
更具可读性的备选方案:
x = df['pairs'].str[0].str.split('/')
df.loc[x.str[0] == 'abc', 'abc'] = x.str[1]
str.get
随心所欲;)
s = df['pairs'].str.get(0).str.split('/')
df['abc'] = np.where(s.str.get(0) == 'abc', s.str.get(1), None)
试试这个
# data
df = pd.DataFrame({
'id': ['1', '2', '3'],
'abc':None,
'pairs': [ ['abc/123', 'foo/345', 'xyz/789'], ['abc/456', 'foo/111', 'xyz/789'], ['xxx/222', 'foo/555', 'xyz/333'] ]
})
# construct a dict in loop and get value of abc key
df['abc'] = df['pairs'].apply(lambda x: dict(e.split('/') for e in x).get('abc'))
df
再次阅读问题后,您似乎只对 abc
键感兴趣,前提是它是列表中的第一个元素,因此与其读取每个列表,不如索引第一个元素并拆分
df['abc'] = df['pairs'].apply(lambda x: dict([x[0].split('/')]).get('abc'))
尝试一下,您不需要 apply
也不需要 lambda 函数:
a = df['pairs'].str[0].str
df['abc'] = a.split('/').str[1].where(a.startswith('abc'))
输出:
id abc pairs
0 1 123 [abc/123, foo/345, xyz/789]
1 2 456 [abc/456, foo/111, xyz/789]
2 3 NaN [xxx/222, foo/555, xyz/333]
注意:str[0] 等于使用 str.get(0).
"Elements in the split lists can be accessed using get or [] notation:"
"你可以重复使用 .str" -> 是的,但是...... 它很慢!
在这种情况下,使用列表理解要好得多:
df['abc'] = [x[1] if (x:=l[0].split('/'))[0].startswith('abc') else float('nan')
for l in df['pairs']]
经验法则:如果您需要 3 str
或更多,最好尝试列表理解!
一张图片胜过千言万语:从 3 行到近 100 万行的性能测试(所有当前答案):
奖励:在任何位置匹配第一个“abc”(不仅是第一个)
df['abc'] = [next((x.split('/')[1] for x in l if x.startswith('abc')), None)
for l in df['pairs']]
我的数据框有一个包含密钥对 list
的列 pairs
。每个键在列表中都是唯一的。例如:
df = pd.DataFrame({
'id': ['1', '2', '3'],
'abc':None,
'pairs': [ ['abc/123', 'foo/345', 'xyz/789'], ['abc/456', 'foo/111', 'xyz/789'], ['xxx/222', 'foo/555', 'xyz/333'] ]
})
数据帧是:
id | abc | pairs
------------------------------------
1 |None | [abc/123, foo/345, xyz/789]
2 |None | [abc/456, foo/111, xyz/789]
3 |None | [xxx/222, foo/555, xyz/333]
如果被 \
拆分的元素 (idx=0) 具有值 (key) ==[=39,则 abc
列将填充 pairs
列中的值=].
预期 df
:
id | abc | pairs
------------------------------------
1 |123 | [abc/123, foo/345, xyz/789]
2 |456 | [abc/456, foo/111, xyz/789]
3 |None | [xxx/222, foo/555, xyz/333]
我在寻找类似的东西:
df.loc[df['pairs'].map(lambda x: 'abc' in (l.split('/')[0] for l in x)), 'abc'] = 'FOUND'
我的问题是用 l.split('/')[0]
您可以重复使用.str
:
df['abc'] = df['pairs'].str[0].str.split('/').loc[lambda x: x.str[0] == 'abc'].str[1]
输出:
>>> df
id abc pairs
0 1 123 [abc/123, foo/345, xyz/789]
1 2 456 [abc/456, foo/111, xyz/789]
2 3 NaN [xxx/222, foo/555, xyz/333]
更具可读性的备选方案:
x = df['pairs'].str[0].str.split('/')
df.loc[x.str[0] == 'abc', 'abc'] = x.str[1]
str.get
随心所欲;)
s = df['pairs'].str.get(0).str.split('/')
df['abc'] = np.where(s.str.get(0) == 'abc', s.str.get(1), None)
试试这个
# data
df = pd.DataFrame({
'id': ['1', '2', '3'],
'abc':None,
'pairs': [ ['abc/123', 'foo/345', 'xyz/789'], ['abc/456', 'foo/111', 'xyz/789'], ['xxx/222', 'foo/555', 'xyz/333'] ]
})
# construct a dict in loop and get value of abc key
df['abc'] = df['pairs'].apply(lambda x: dict(e.split('/') for e in x).get('abc'))
df
再次阅读问题后,您似乎只对 abc
键感兴趣,前提是它是列表中的第一个元素,因此与其读取每个列表,不如索引第一个元素并拆分
df['abc'] = df['pairs'].apply(lambda x: dict([x[0].split('/')]).get('abc'))
尝试一下,您不需要 apply
也不需要 lambda 函数:
a = df['pairs'].str[0].str
df['abc'] = a.split('/').str[1].where(a.startswith('abc'))
输出:
id abc pairs
0 1 123 [abc/123, foo/345, xyz/789]
1 2 456 [abc/456, foo/111, xyz/789]
2 3 NaN [xxx/222, foo/555, xyz/333]
注意:str[0] 等于使用 str.get(0).
"Elements in the split lists can be accessed using get or [] notation:"
"你可以重复使用 .str" -> 是的,但是...... 它很慢!
在这种情况下,使用列表理解要好得多:
df['abc'] = [x[1] if (x:=l[0].split('/'))[0].startswith('abc') else float('nan')
for l in df['pairs']]
经验法则:如果您需要 3 str
或更多,最好尝试列表理解!
一张图片胜过千言万语:从 3 行到近 100 万行的性能测试(所有当前答案):
奖励:在任何位置匹配第一个“abc”(不仅是第一个)
df['abc'] = [next((x.split('/')[1] for x in l if x.startswith('abc')), None)
for l in df['pairs']]