(我很害怕这些问题......)
所以我通过一个非常费力的大熊猫学习过程得到了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
网址列可以说很多不同的内容,但它们都包含“查看结束”,并且不会一致地指出右边的哪个列包含网站。
我想做一些事情,首先,将网站从任何Notes列移到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查找Notes列。例如,如果我尝试使用上述方法作为条件,例如:
if df['Notes1'].str.lower().str.contains('www'):
df.loc[to_move, 'URL'] = df['Notes1']
我回来ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
但是添加.any()
或.all()
有明显的缺陷,他们没有给我我正在寻找的东西:任何,例如,每一行满足URL中的to_move要求将获得Notes1中的任何内容。我需要逐行检查。出于类似的原因,我甚至无法开始折叠Notes列(我不知道如何检查非空的空字符串单元格,这也是我此时创建的一个问题。)
在它所代表的位置,我知道我还必须在满足第一个条件的情况下将Notes2移入Notes1,将Notes3移至Notes2,并移至Notes3,因为我不希望Notes列中的剩余URL。我敢肯定大熊猫有比我正在做的更容易的路线,因为它是熊猫,当我尝试用熊猫做任何事情时,我发现它可以在一行而不是我的20 ...
(PS,我不关心空列Notes2和Notes3是否遗留下来,b / c我在下一步我的CSV导入中没有使用它们,尽管我总是可以学到比我需要的更多)
更新:所以我一次一步地使用我的非熊猫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重复)我知道必须有一个更有效的方法...这也不会在Notes列中崩溃,但使用相同的方法应该很容易,除了我仍然不知道找到空字符串的好方法。
答案 0 :(得分:1)
我还在学习大熊猫,所以这些代码的某些部分可能不那么优雅,但一般的想法是 - 获取所有笔记列,找到所有网址,将其与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