我正在尝试使用txt文件中存储的大量数据来构造数据帧。但是,我没有构造数据,因此我必须使用其中包含的令人沮丧的格式。我无法使我的代码在大数据中运行(并且几乎使我的计算机崩溃了),因此设置一个较小的数据框,如下所示:
'Value' ID_1 ID_2
0 11122222 ABC42123 33333
1 21219299 YOF21233 88821
2 00022011 ERE00091 23124
3 75643311;21233332 ROB21288 99421
4 12412421 POW94277 12231;33221
5 54221721 IRS21231;YOU28137 13123
我的沮丧之处在于在数据中使用分号。该数据用于表示ID,但已将多个ID分配给多个变量。我想重复这些行,以便可以在数据中搜索各个ID,并拥有一个如下所示的数据表:
'Value' ID_1 ID_2
0 11122222 ABC42123 33333
1 21219299 YOF21233 88821
2 00022011 ERE00091 23124
3 75643311 ROB21288 99421
4 21233332 ROB21288 99421
5 12412421 POW94277 12231
6 12412421 POW94277 33221
7 54221721 YOU28137 13123
8 54221721 IRS21231 13123
重新索引不是问题,只要不同的ID彼此保持链接并保持其正确值即可。
不幸的是,到目前为止,我所有分割数据的尝试都以失败告终。我设法建立了一个函数,该函数可重复包含分号的数据,并通过我的函数为每一列进行解析,但随后无法拆分数据。
def delete_dup(df,column):
for a in column:
location = df.loc[df.duplicated(subset= column, keep=False)]
for x in location:
semicolon = df.loc[df[column].str.contains(';', regex=True)]
duplicate = semicolon.duplicated(subset= column, keep='first')
tiny_df = semicolon.loc[duplicate]
split_up = tiny_df[column].str.split(';')
return pd.concat([df, split_up])
'Value' ID_1 ID_2 0
11122222 ABC42123 33333 NaN
21219299 YOF21233 88821 NaN
00022011 ERE00091 23124 NaN
75643311;21233332 ROB21288 99421 NaN
12412421 POW94277 12231;33221 NaN
54221721 IRS21231;YOU28137 13123 NaN
75643311;21233332 ROB21288 99421 NaN
54221721 IRS21231;YOU28137 13123 NaN
12412421 POW94277 12231;33221 NaN
NaN NaN NaN [75643311, 21233332]
我觉得这是我最近来过的地方,但距离我想要的地方还很遥远。我尝试在数据帧上执行的所有“ If”语句都遇到“ ValueError:DataFrame的真值不明确。请使用a.empty,a.bool(),a.item(),a.any()或a.all()。”错误,阅读起来实在令人沮丧。关于如何让熊猫做我想要的任何想法?
答案 0 :(得分:0)
也许不是最优雅的方式,但是 可以解决问题:
第1步
我们拥有的数据:
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api-java9</artifactId>
<version>${log4j.version}</version>
</dependency>
第2步
让我们拆分行为异常的列
df
'Value' ID_1 ID_2
0 11122222 ABC42123 33333
1 21219299 YOF21233 88821
2 00022011 ERE00091 23124
3 75643311;21233332 ROB21288 99421
4 12412421 POW94277 12231;33221
5 54221721 IRS21231;YOU28137 13123
第3步
让我们将重复数据和原始数据合并为一个数据帧:
df["'Value'_Dupe"] = df["'Value'"].apply(lambda x: x.split(";")[1] if len(x.split(";"))>1 else np.NaN)
df["'Value'"] = df["'Value'"].apply(lambda x: x.split(";")[0])
df["ID_1_Dupe"] = df["ID_1"].apply(lambda x: x.split(";")[1] if len(x.split(";"))>1 else np.NaN)
df["ID_1"] = df["ID_1"].apply(lambda x: x.split(";")[0])
df["ID_2_Dupe"] = df["ID_2"].apply(lambda x: x.split(";")[1] if len(x.split(";"))>1 else np.NaN)
df["ID_2"] = df["ID_2"].apply(lambda x: x.split(";")[0])
df
'Value' ID_1 ID_2 'Value'_Dupe ID_1_Dupe ID_2_Dupe
0 11122222 ABC42123 33333 NaN NaN NaN
1 21219299 YOF21233 88821 NaN NaN NaN
2 00022011 ERE00091 23124 NaN NaN NaN
3 75643311 ROB21288 99421 21233332 NaN NaN
4 12412421 POW94277 12231 NaN NaN 33221
5 54221721 IRS21231 13123 NaN YOU28137 NaN
请告诉我这是否可以解决您的问题。
答案 1 :(得分:0)
解决方案分为两部分。第一个是识别哪些行带有分号,第二个是创建其他行并将其连接起来。第一部分在contains_sc
中完成,第二部分通过遍历行并在检测到带有分号的行时运行函数create_additional_rows
来完成。
希望这会有所帮助。
In[6]: import pandas as pd
In[7]: df = pd.DataFrame(
[['1', '2;3', '4', '5'],
['A', 'B', 'C', 'D;E'],
['T', 'U', 'V;W', 'X']],
index=['Val', 'ID1', 'ID2']
).T
In[8]: df
Out[8]:
Val ID1 ID2
0 1 A T
1 2;3 B U
2 4 C V;W
3 5 D;E X
In[9]: contains_sc = df.apply(lambda x: x.str.contains(';'))
In[10]: contains_sc
Out[10]:
Val ID1 ID2
0 False False False
1 True False False
2 False False True
3 False True False
In[11]:
def create_additional_rows(data_row, csc_row, split_char=';'):
"""Given a duplicated row return additional de-duplicated rows."""
if len(csc_row[csc_row].dropna()) > 1:
raise ValueError('Expect only a single column with a semicolon')
col_with_sc = csc_row[csc_row].dropna().index[0]
retval = []
for item in data_row.loc[col_with_sc].split(split_char):
copied = data_row.copy()
copied.loc[col_with_sc] = item
retval.append(copied)
return retval
In[11]:
new_rows = []
for (idx, data_row), (_, csc_row) in zip(df.iterrows(), contains_sc.iterrows()):
if True not in csc_row.values:
new_rows.append(data_row)
continue
new_rows.extend(create_additional_rows(data_row, csc_row))
final = pd.concat(new_rows, axis='columns').T.reset_index(drop=True)
In[13]: final
Out[13]:
Val ID1 ID2
0 1 A T
1 2 B U
2 3 B U
3 4 C V
4 4 C W
5 5 D X
6 5 E X