gpt4 book ai didi

python - 按行设置列的 pandas 条件,Python 2.7

转载 作者:太空宇宙 更新时间:2023-11-03 18:44:17 26 4
gpt4 key购买 nike

(我不擅长给这些问题起标题......)

通过 pandas 的艰苦学习过程,我已经完成了 90% 的任务,但我还有一件事需要弄清楚。让我展示一个示例(实际原始文件是一个以逗号分隔的 CSV,其中包含更多行):

 Name    Price    Rating    URL                Notes1       Notes2            Notes3
Foo $450 9 a.com/x NaN NaN NaN
Bar $99 5 see over www.b.com Hilarious Nifty
John $551 2 www.c.com Pretty NaN NaN
Jane $999 8 See Over in Notes Funky http://www.d.com Groovy

URL 列可以表示许多不同的内容,但它们都包含“查看”,并且不能一致地指示右侧的哪一列包含该网站。

我想做一些事情,在这里:首先,将网站从任何“注释”列移动到 URL;其次,将所有注释列折叠为一列,并在它们之间换行。所以这个(NaN被删除,因为pandas让我为了在df.loc中使用它们):

 Name    Price    Rating    URL                Notes1       
Foo $450 9 a.com/x
Bar $99 5 www.b.com Hilarious
Nifty
John $551 2 www.c.com Pretty
Jane $999 8 http://www.d.com Funky
Groovy

我这样做已经完成了一半:

 df['URL'] = df['URL'].fillna('')
df['Notes1'] = df['Notes1'].fillna('')
df['Notes2'] = df['Notes2'].fillna('')
df['Notes3'] = df['Notes3'].fillna('')
to_move = df['URL'].str.lower().str.contains('see over')
df.loc[to_move, 'URL'] = df['Notes1']

我不知道如何找到带有 www 或 .com 的注释栏。例如,如果我尝试使用我的上述方法作为条件,例如:

 if df['Notes1'].str.lower().str.contains('www'):
df.loc[to_move, 'URL'] = df['Notes1']

我得到ValueError:具有多个元素的数组的真值不明确。使用 a.any() 或 a.all() 但是添加 .any().all() 有一个明显的缺陷,它们没有给我我正在寻找的东西:对于任何,例如,满足 URL 中 to_move 要求的每一行都将获得 Notes1 中的任何内容。我需要逐行进行检查。出于类似的原因,我什至无法开始折叠注释列(而且我也不知道如何检查非空空字符串单元格,这是我此时创建的问题)。

就目前情况而言,我知道当满足第一个条件时,我还必须将 Notes2 移至 Notes1,将 Notes3 移至 Notes2,并将 '' 移至 Notes3,因为我不希望 Notes 列中残留 URL。我确信 pandas 的路线比我正在做的更简单,因为它是 pandas,当我尝试用 pandas 做任何事情时,我发现它可以在一行中完成,而不是我的 20...

(PS,我不在乎是否留下空列 Notes2 和 Notes3,因为我不会在下一步的 CSV 导入中使用它们,尽管我总是可以学到比我需要的更多的东西)

更新:所以我一步一步地使用我的非 Pandas Python逻辑找到了一个糟糕的冗长解决方案。我想出了这个(与上面相同的前五行,减去 df.loc 行):

url_in1 = df['Notes1'].str.contains('\.com')
url_in2 = df['Notes2'].str.contains('\.com')
to_move = df['URL'].str.lower().str.contains('see-over')
to_move1 = to_move & url_in1
to_move2 = to_move & url_in2
df.loc[to_move1, 'URL'] = df.loc[url_in1, 'Notes1']
df.loc[url_in1, 'Notes1'] = df['Notes2']
df.loc[url_in1, 'Notes2'] = ''
df.loc[to_move2, 'URL'] = df.loc[url_in2, 'Notes2']
df.loc[url_in2, 'Notes2'] = ''

(在实际代码中移动的行和重复的 to_move)我知道必须有一个更有效的方法...这也不会在注释列中崩溃,但是使用相同的方法应该很容易,除了我仍然不知道找到空字符串的好方法。

最佳答案

我还在学习 pandas,所以这段代码的某些部分可能不是那么优雅,但总体思路是 - 获取所有注释列,找到其中的所有 url,将其与 URL 列结合起来然后将剩余的注释连接到 Notes1 列中:

import pandas as pd
import numpy as np
import pandas.core.strings as strings

# Just to get first notnull occurence
def geturl(s):
try:
return next(e for e in s if not pd.isnull(e))
except:
return np.NaN

df = pd.read_csv("d:/temp/data2.txt")

dfnotes = df[[e for e in df.columns if 'Notes' in e]]

# Notes1 Notes2 Notes3
# 0 NaN NaN NaN
# 1 www.b.com Hilarious Nifty
# 2 Pretty NaN NaN
# 3 Funky http://www.d.com Groovy

dfurls = dfnotes.apply(lambda x: x.str.contains('\.com'), axis=1)
dfurls = dfurls.fillna(False).astype(bool)

# Notes1 Notes2 Notes3
# 0 False False False
# 1 True False False
# 2 False False False
# 3 False True False

turl = dfnotes[dfurls].apply(geturl, axis=1)

df['URL'] = np.where(turl.isnull(), df['URL'], turl)
df['Notes1'] = dfnotes[~dfurls].apply(lambda x: strings.str_cat(x[~x.isnull()], sep=' '), axis=1)

del df['Notes2']
del df['Notes3']

df
# Name Price Rating URL Notes1
# 0 Foo $450 9 a.com/x
# 1 Bar $99 5 www.b.com Hilarious Nifty
# 2 John $551 2 www.c.com Pretty
# 3 Jane $999 8 http://www.d.com Funky Groovy

关于python - 按行设置列的 pandas 条件,Python 2.7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19897558/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com