gpt4 book ai didi

python - 使用 Panda 在 Python 中根据名称查找值之间的关系

转载 作者:行者123 更新时间:2023-12-03 14:21:23 25 4
gpt4 key购买 nike

我想根据以下规则按名称建立值之间的关系:
1- 我有一个包含大量值的 CSV 文件(超过 100000 行),我分享了一些示例,如下所示:

    Name:
A02-father
A03-father
A04-father
A05-father
A07-father
A08-father
A09-father
A17-father
A18-father
A20-father
A02-SA-A03-SA
A02-SA-A04-SA
A03-SA-A02-SA
A03-SA-A05-SA
A03-SA-A17-SA
A04-SA-A02-SA
A04-SA-A09-SA
A05-SA-A03-SA
A09-SA-A04-SA
A09-SA-A20-SA
A17-SA-A03-SA
A17-SA-A18-SA
A18-SA-A17-SA
A20-SA-A09-SA
A05-NA
B02-Father
B04-Father
B06-Father
B02-SA-B04-SA
B04-SA-BO2-SA
B04-SA-B06-SA
B06-SA-B04-SA
B06-NA
2- 现在我有另一个 CSV 文件,它让我知道我应该从哪个值开始?在这种情况下,该值为
A03-father & B02-father & ... 相互之间没有任何影响,而且都有各自的路径,所以对于每条路径,我们将从提到的起点开始。
父亲.csv
A03-父亲
B02-父亲
....
3-根据我想建立关系的命名,由于A03-Father已被确定为Father,我应该检查以A03开头的任何值。(所有这些都是A0的婴儿。)
此外,由于 B02 是父亲,我们将检查以 B02 开头的任何值。 (B02-SA-B04-SA)
4- 现在如果我发现 A03-SA- A02 -SA,这是A03的宝贝。
我找到了 A03-SA- A05 -SA,这是A03的宝贝。
我找到了 A03-SA- A17 -SA,这是A03的宝贝。
之后我必须检查以 A02 & A05 & A17 开头的任何节点:
正如你看到的 A02-Father 存在所以它是父亲,现在我们将搜索任何以 A02 和 开头的字符串。没有被检测为父亲的 A03(必须忽略)
这必须检查直到 CSV 文件中存在的值结束。
如您所见,我应该根据名称(REGEX)检查路径,并且应该前进到路径末尾。
预期结果:
    Father      Baby
A03-father A03-SA-A02-SA
A03-father A03-SA-A05-SA
A03-father A03-SA-A17-SA
A02-father A02-SA-A04-SA
A05-father A05-NA
A17-father A17-SA-A18-SA
A04-father A04-SA-A09-SA
A02-father A02-SA-A04-SA
A09-father A09-SA-A20-SA
B02-father B02-SA-B04-SA
B04-father B04-SA-B06-SA
B06-father B06-NA
我用 Pandas 编码如下:
import pandas as pd
import numpy as np
import re

#Read the file which consists of all Values
df = pd.read_csv("C:\\total.csv")


#Read the file which let me know who is father
Fa = pd.read_csv("C:\\Father.csv")

#Get the first part of Father which is A0
Fa['sub'] = Fa['Name'].str.extract(r'(\w+\s*)', expand=False)
r2 = []

#check in all the csv file and find anything which starts with A0 and is not Father
for f in Fa['sub']:
baby=(df[df['Name'].str.startswith(f) & ~df['Name'].str.contains('Father')])
baby['sub'] = bay['Name'].str.extract(r'(\w+\s*)', expand=False)
r1= pd.merge(Fa, baby, left_on='sub', right_on='sub',suffixes=('_f', '_c'))
r2.append(result1)
out_df = pd.concat(result2)
out_df= out_df.replace(np.nan, '', regex=True)
#find A0-N-A2-M and A0-N-A4-M
out_df.to_csv('C:\\child1.csv')



#check in all the csv file and find anything which starts with the second part of child1 which is A2 and A4
out_df["baby2"] = out_df['Name_baby'].str.extract(r'^(?:[^-]*-){2}\s*([^-]+)', expand=False)
baby3= out_df["baby2"]
r4 = []
for f in out_df["baby2"]:
#I want to exclude A0 which has been detected.
l = ['A0']
regstr = '|'.join(l)
baby1=(df[df['Name'].str.startswith(f) & ~df['Name'].str.contains(regstr)])
baby1['sub'] = baby1['Name'].str.extract(r'(\w+\s*)', expand=False)

r3= pd.merge(baby3, baby1, left_on='baby2', right_on='sub',suffixes=('_f', '_c'))
r4.append(r3)
out2_df = pd.concat(r4)
out2_df.to_csv('C:\\child2.csv')
我想将下面的代码放在一个循环中并遍历文件并检查它,基于命名过程并检测其他父亲和婴儿直到完成。但是,此代码不是自定义的,并且没有我预期的确切结果。
我的问题是如何制作循环?
我应该通过路径并考虑regstr任何字符串的值。
#check in all the csv file and find anything which starts with the second part of child1 which is A2 and A4

out_df["baby2"] = out_df['Name_baby'].str.extract(r'^(?:[^-]*-){2}\s*([^-]+)', expand=False)
baby3= out_df["baby2"]
r4 = []
for f in out_df["baby2"]:
#I want to exclude A0 which has been detected.
l = ['A0']
regstr = '|'.join(l)
baby1=(df[df['Name'].str.startswith(f) & ~df['Name'].str.contains(regstr)])
baby1['sub'] = baby1['Name'].str.extract(r'(\w+\s*)', expand=False)

r3= pd.merge(baby3, baby1, left_on='baby2', right_on='sub',suffixes=('_f', '_c'))
r4.append(r3)
out2_df = pd.concat(r4)
out2_df.to_csv('C:\\child2.csv')

最佳答案

import collections 开始(很快就会需要)。
我假设您已经阅读了 df 和 Fa DataFrames。
我的代码的第一部分是创建子系列(索引 - 父级,
值(value) - child ):

isFather = df.Name.str.contains('-father', case=False)
dfChildren = df[~isFather]
key = []; val = []
for fath in df[isFather].Name:
prefix = fath.split('-')[0]
for child in dfChildren[dfChildren.Name.str.startswith(prefix)].Name:
key.append(prefix)
val.append(child)
children = pd.Series(val, index=key)
打印 child 以查看结果。
第二部分是创建实际结果,从每个
法的起点:
nodes = collections.deque()
father = []; baby = [] # Containers for source data
# Loop for each starting point
for startNode in Fa.Name.str.split('-', expand=True)[0]:
nodes.append(startNode)
while nodes:
node = nodes.popleft() # Take node name from the queue
# Children of this node
myChildren = children[children.index == node]
# Process children (ind - father, val - child)
for ind, val in myChildren.items():
parts = val.split('-') # Parts of child name
# Child "actual" name (if exists)
val_2 = parts[2] if len(parts) >= 3 else ''
if val_2 not in father: # val_2 not "visited" before
# Add father / child name to containers
father.append(ind)
baby.append(val)
if len(val_2) > 0:
nodes.append(val_2) # Add to the queue, to be processe later
# Drop rows for "node" from "children" (if any exists)
if (children.index == node).sum() > 0:
children.drop(node, inplace=True)
# Convert to a DataFrame
result = pd.DataFrame({'Father': father, 'Baby': baby})
result.Father += '-father' # Add "-father" to "bare" names
我用小写“f”添加了-father,但我认为这并不多
重要的细节。
对于您的数据样本,结果是:
        Father           Baby
0 A03-father A03-SA-A02-SA
1 A03-father A03-SA-A05-SA
2 A03-father A03-SA-A17-SA
3 A02-father A02-SA-A04-SA
4 A05-father A05-NA
5 A17-father A17-SA-A18-SA
6 A04-father A04-SA-A09-SA
7 A09-father A09-SA-A20-SA
8 B02-father B02-SA-B04-SA
9 B04-father B04-SA-B06-SA
10 B06-father B06-NA
以及关于您的数据样本的两点评论:
  • 你用大写的 O(一个字母)而不是 0 写了 B04-SA-B02-SA
    (零)。我在我的源数据中更正了它。
  • A02-father A02-SA-A04-SA在您的预期结果中翻了一番。
    我认为它应该只发生一次。
  • 关于python - 使用 Panda 在 Python 中根据名称查找值之间的关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65046975/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com