Python 根据另一列的特定值将一行中的单词拆分为几行
我有这个数据帧df:Python 根据另一列的特定值将一行中的单词拆分为几行,python,pandas,Python,Pandas,我有这个数据帧df: columnId column2 column3 countsOfWord id1 hogedijk klarenbeek 2016 2 id2 hogedijk klaren
columnId column2 column3 countsOfWord
id1 hogedijk klarenbeek 2016 2
id2 hogedijk klarenbeek zuidoost hogedijk klarenbeek zuidoost 2012 6
id3 zuidoost clouds 2010 2
id4 artzuid zuidoost hogedijk klarenbeek zuidoost clouds hogedijk klarenbeek 2019 8
df['column2'].iloc[1][0:len(df['column2'].iloc[0])//2]
我迫切需要将countsOfWords上面的行(如id2和id4拆分为相等的部分),以便这些行的countsOfWords列只包含两个单词,而不改变列ID和第3列。我的df数据帧如下所示:
columnId column2 column3 countsOfWord
id1 hogedijk klarenbeek 2016 2
id2 hogedijk klarenbeek 2012 2
id2 zuidoost hogedijk 2012 2
id2 klarenbeek zuidoost 2012 2
id3 zuidoost clouds 2010 2
id4 artzuid zuidoost 2019 2
id4 hogedijk klarenbeek 2019 2
id4 zuidoost clouds 2019 2
id4 hogedijk klarenbeek 2019 2
有人能帮我吗
我尝试了这段代码,但它不会自动为countsOfWords以上两次:
columnId column2 column3 countsOfWord
id1 hogedijk klarenbeek 2016 2
id2 hogedijk klarenbeek zuidoost hogedijk klarenbeek zuidoost 2012 6
id3 zuidoost clouds 2010 2
id4 artzuid zuidoost hogedijk klarenbeek zuidoost clouds hogedijk klarenbeek 2019 8
df['column2'].iloc[1][0:len(df['column2'].iloc[0])//2]
您可以尝试此操作(使用str.split()
和zip()
然后):
印刷品:
columnId column2 column3 countsOfWord
0 id1 hogedijk klarenbeek 2016 2
1 id2 hogedijk klarenbeek 2012 2
1 id2 zuidoost hogedijk 2012 2
1 id2 klarenbeek zuidoost 2012 2
2 id3 zuidoost clouds 2010 2
3 id4 artzuid zuidoost 2019 2
3 id4 hogedijk klarenbeek 2019 2
3 id4 zuidoost clouds 2019 2
3 id4 hogedijk klarenbeek 2019 2
IIUC我们进行
分解
然后cumcount
将组拆分为子组
s=df.assign(column2=df.column2.str.split(' ')).explode('column2')
s=s.groupby([s.columnId,s.groupby('columnId').cumcount()//2]).\
agg({'columnId':'first','column2':' '.join,'column3':'first','countsOfWord':'first'})
s=s.assign(countsOfWord=2).reset_index(drop=True)
s
columnId column2 column3 countsOfWord
0 id1 hogedijk klarenbeek 2016 2
1 id2 hogedijk klarenbeek 2012 2
2 id2 zuidoost hogedijk 2012 2
3 id2 klarenbeek zuidoost 2012 2
4 id3 zuidoost clouds 2010 2
5 id4 artzuid zuidoost 2019 2
6 id4 hogedijk klarenbeek 2019 2
7 id4 zuidoost clouds 2019 2
8 id4 hogedijk klarenbeek 2019 2
或findall
+explode
df.assign(column2=df.column2.str.replace(' ','-').str.findall("-".join(["[^-]+"] * 2))).explode('column2')
columnId column2 column3 countsOfWord
0 id1 hogedijk-klarenbeek 2016 2
1 id2 hogedijk-klarenbeek 2012 6
1 id2 zuidoost-hogedijk 2012 6
1 id2 klarenbeek-zuidoost 2012 6
2 id3 zuidoost-clouds 2010 2
3 id4 artzuid-zuidoost 2019 8
3 id4 hogedijk-klarenbeek 2019 8
3 id4 zuidoost-clouds 2019 8
3 id4 hogedijk-klarenbeek 2019 8
我们可以将您的值拆分为一个列表,然后将它们拆分为两个元素的相等块 然后我们检查元素数
>2
和分解的位置,这些行:
splitted = df['column2'].str.split()
lists = splitted.apply(lambda lst: [lst[i::len(lst)//2] for i in range(len(lst)//2)])
df['column2'] = np.where(splitted.str.len().gt(2), lists, df['column2'])
dfn = df.explode('column2')
dfn['column2'] = np.where(
dfn['column2'].apply(type).eq(list),
dfn['column2'].str.join(', '),
dfn['column2']
)
dfn['countsOfWord'] = dfn['column2'].str.split().str.len()
我会把它作为一个列表来处理
tb = [['id1', 'hogedijk klarenbeek', 2016],
['id2', 'hogedijk klarenbeek zuidoost hogedijk klarenbeek zuidoost', 2012],
['id3', 'hogedijk klarenbeek', 2010],
['id4', 'artzuid zuidoost hogedijk klarenbeek zuidoost clouds hogedijk klarenbeek', 2019]]
COL_1 = 0
COL_2 = 1
COL_3 = 2
SPACE = ' '
new_tb = []
for line in tb:
words = line[COL_2].split(SPACE)
while len(words) != 0:
new_line = [line[COL_1]]
new_word_set = words.pop(0)
new_word_set += SPACE + words.pop(0)
new_line.append(new_word_set)
new_line.append(line[COL_3])
new_tb.append(new_line)
print(pd.DataFrame(new_tb))
这将实现以下目的:
df[“column2”]=df[“column2”].str.split(r)((?:([^\s]+\s+[^\s]+)\s+)
df=df.explode(“column2”).query(“column2!=”)
#如果给定uou,则其字数始终为偶数:
df[“countOfWords”]=2
#否则:
df[“countOfWords”]=df[“column2”].str.count(r“\s”).add(1)
输出:
columnId column2 column3 countOfWords
0 id1 hogedijk klarenbeek 2016 2
1 id2 hogedijk klarenbeek 2012 2
1 id2 Zuidost hogedijk 2012 2
1 id2 klarenbeek zuidoost 2012 2
2 id3 hogedijk klarenbeek 2010 2
3 id4 artzuid Zuidost 2019 2
3 id4 hogedijk klarenbeek 2019 2
3 id4 zuidoost云2019 2
3 id4 hogedijk klarenbeek 2019 2
现在要分解它:
columnId column2 column3 countsOfWord
id1 hogedijk klarenbeek 2016 2
id2 hogedijk klarenbeek zuidoost hogedijk klarenbeek zuidoost 2012 6
id3 zuidoost clouds 2010 2
id4 artzuid zuidoost hogedijk klarenbeek zuidoost clouds hogedijk klarenbeek 2019 8
df['column2'].iloc[1][0:len(df['column2'].iloc[0])//2]
这里唯一棘手的部分是正则表达式:
(?:([^\s]+\s+[^\s]+)\s+
\s
表示单个空白
\s+
代表一个或多个空格(为了安全起见)
[^\s]+
表示一个或多个非
空白字符
(?:…)
将冒号后的模式用作分隔符的前面部分
因此,本质上,您可以按以下方式拆分:一个或多个空格,前面是(整个内容)一个或多个非空格字符,后面是一个或多个空格,后面是一个或多个非空格字符。我不明白为什么第一行代码不起作用。我这样试过:
s=df.assign(['column2']=df['column2']].str.split('').explode('column2')
我认为在处理数据帧时应该避免纯python循环。请参阅本文:stackoverflow.com/a/55557758/10254804为什么说dataframe对象没有属性explode?@JackZakiZakiulFahmiJailani您使用的是什么版本的pandas
explode()
是在版本0.25.0
中引入的,我尝试了这一点,但显然在我在@Erfan应用此代码后出现了数据丢失