我有一个有3列的数据框架(df)。 最后两列(word1和word2)是动态创建的(基于代码前面的用户输入):
**Title word1 word2**
tl1 er fg
tl2
tl3 ghj
tl4 hjk
tl5 dfg gh
tl6 dfk
tl7
...
现在我要做的是删除word1和word2都为空的所有行,因此在上面的示例中,我将得到:
**Title word1 word2**
tl1 er fg
tl3 ghj
tl4 hjk
tl5 dfg gh
tl6 dfk
...
由于列是动态生成的,我不知道它们的名称。 然而,我所知道的是,它们是从一个列表中生成的(该列表也是通过用户输入生成的)。 该列表如下所示:wordlist=['word1','word2']
(根据用户输入,它们也可以是'word10'&'word21')
所以为了删除空行,我可以使用这两行:
indexNames = df[(df['word1'] == '') & (df['word2'] == '')].index
df.drop(indexNames , inplace=True)
但是,由于我不知道列的名称,我尝试做一些动态的事情,如下所示:
columnString=""
for word in wordList:
if (columnString == ""):
columnString = "(df['" + word + "'] == '')"
else:
columnString = columnString + " & (df['" + word + "'] == '')"
然后执行:print(columnString)
我得到:(df['word1']=='')&; (df['word2']=='')
因此,从这里开始,我想可以做以下工作(利用不知道列名的优势):
indexNames = df[columnString].index
df.drop(indexNames , inplace=True)
结果应该和下面的完全一样(完美工作,但不是动态的):
indexNames = df[(df['word1'] == '') & (df['word2'] == '')].index
df.drop(indexNames , inplace=True)
但是,对于使用字符串组成的版本,我会得到一个KeyError:
KeyError: "(df['skal'] == '') & (df['sap'] == '')"
我来自C#,在C#中,操作的操作/动态创建非常简单。 我猜在Python中也有可能做到这一点,但如何做到呢?
只需使用两个变量,例如name1
和name2
,而不是硬编码字符串'word1'
和'word2'
。 变量name1
和name2
可以采用您希望的任何字符串值。
name1 = 'word1'
name2 = 'word2'
indexNames = df[(df[name1] == '') & (df[name2] == '')].index
df.drop(indexNames , inplace=True)
或者,从列表
开始,说名称
:
def multi_bitwise_and(items):
iter_items = iter(items)
result = next(iter_items)
for item in iter_items:
result = result & item
return result
indexNames = df[multi_bitwise_and((df[name] == '') for name in names)].index
df.drop(indexNames , inplace=True)
使用,dataframe.eq
创建一个布尔掩码,然后在此掩码上使用dataframe.all
沿着axis=1
创建另一个布尔掩码M
,其中真实值对应于wordlis
中沿给定行的列中的所有值都为empty
的条件,然后使用此掩码筛选数据帧:
wordList = ['word1', 'word2']
m = df[wordList].eq('').all(axis=1)
df = df[~m]
结果:
# print(df)
Title word1 word2
0 tl1 er fg
2 tl3 ghj
3 tl4 hjk
4 tl5 dfg gh
5 tl6 dfk