如何复制和修改Pandas数据帧中的行?

2024-10-08 18:24:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用存储在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,并得到一个如下所示的datatable:

^{pr2}$

重新编制索引不是问题,只要不同的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:数据帧的真值不明确”。使用a.empty、a.bool()、a.item()、a.any()或a.all()。这是一个非常令人沮丧的错误。有什么办法让熊猫做我想做的吗?在


Tags: 数据iddfvaluecolumnnanlocsplit
2条回答

也许不是最优雅的方式,但这种只是解决了问题:

第1步

我们掌握的数据:

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

第2步

让我们把行为不端的列分开

^{pr2}$

第3步

让我们将复制与原始数据合并到单个数据帧中:

df2 = df[pd.notna(df["'Value'_Dupe"])][["'Value'_Dupe","ID_1","ID_2"]]
df2.columns = ["'Value'","ID_1","ID_2"]

df3 = df[pd.notna(df["ID_1_Dupe"])][["'Value'","ID_1_Dupe","ID_2"]]
df3.columns = ["'Value'","ID_1","ID_2"]

df4 = df[pd.notna(df["ID_2_Dupe"])][["'Value'","ID_1","ID_2_Dupe"]]
df4.columns = ["'Value'","ID_1","ID_2"]

df5 = df[["'Value'","ID_1","ID_2"]]

df_result = pd.concat([df5,df2,df3,df4])
df_result



    'Value'     ID_1        ID_2
0   11122222    ABC42123    33333
1   21219299    YOF21233    88821
2   00022011    ERE00091    23124
3   75643311    ROB21288    99421
4   12412421    POW94277    12231
5   54221721    IRS21231    13123
3   21233332    ROB21288    99421
5   54221721    YOU28137    13123
4   12412421    POW94277    33221

如果这能解决你的问题,请告诉我。在

解决方案有两个部分。第一种方法是确定哪些行有分号,第二种方法是创建额外的行并将它们连接起来。第一部分在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

相关问题 更多 >

    热门问题