Python 一列中的多个条目更改数据帧中的输出

Python 一列中的多个条目更改数据帧中的输出,python,string,pandas,dataframe,Python,String,Pandas,Dataframe,我有一个DF,如下所示 DF_Old= ID NER tID POS令牌R 1 B-ORG 1 NNP大学“华盛顿大学地震学实验室+华盛顿大学地震学实验室*wash” “华盛顿大学地震学实验室*华盛顿大学地震学实验室*wash”的1 I-ORG1 IN 1 I-ORG 1 NNP华盛顿“OrgBased_In+华盛顿大学地震实验室*wash” 1 I-ORG 1 NNP地震学“OrgBased_In+华盛顿大学地震学实验室*wash” 1 L-ORG 1 NNP实验室“OrgBased_In+华

我有一个DF,如下所示

DF_Old=
ID NER tID POS令牌R
1 B-ORG 1 NNP大学“华盛顿大学地震学实验室+华盛顿大学地震学实验室*wash”
“华盛顿大学地震学实验室*华盛顿大学地震学实验室*wash”的1 I-ORG1 IN
1 I-ORG 1 NNP华盛顿“OrgBased_In+华盛顿大学地震实验室*wash”
1 I-ORG 1 NNP地震学“OrgBased_In+华盛顿大学地震学实验室*wash”
1 L-ORG 1 NNP实验室“OrgBased_In+华盛顿大学地震实验室*wash”
1 U-LOC 22 NNP wash“华盛顿大学地震实验室OrgBased_.*wash”
除了column
R
之外,所有列都应该是非常自我解释的。此列包含行的标签(OrgBased_In)及其方向。表示“+”后面和“*”前面的字符属于第一个参数,“*”后面的字符属于第二个参数。现在,我想将这些重要信息(以及NER的标签)过滤到一个新列
Relations

我执行了许多必要的步骤来获得我想要的DF

DF["Re"]= DF.R.str.findall(r"(Kill|Live_In|Located_In|OrgBased_In|Work_For)\+").str.join(',')
DF["Re"]= DF["Re"].str.split(',').apply(set).str.join(',')
DF["Argument1"] = DF["R"].str.split('+').str[+1]
DF["Argument1"] = DF["Argument1"].str.split('*').str[0]
DF["Argument2"] = DF["R"].str.split('*').str[-1]
DF["Argument2"] = DF["Argument2"].str.split(',').str[0]
DF["Argument1"] = DF["Argument1"].fillna("N")
DF["Argument2"] = DF["Argument2"].fillna("N")

conditions = [[x[0] in x[1] for x in zip(DF['token'].replace("-\d[\d]*","", regex=True), DF['Argument1'])], 
              [x[0] in x[1] for x in zip(DF['token'].replace("-\d[\d]*","", regex=True), DF['Argument2'])]]
choices = ["ARG1", "ARG2"]

DF["ARG"] = np.select(conditions, choices, default="O")
DF["Re"] = used_testing_global["Re"].str.split(',').str[0]
DF["Relations"] = DF["Re"] + "-" + DF["ARG"] + "-" + DF["NER"].str.split("-").str[0]
删除所有不必要的列后,我得到以下(正确)结果:

DF_新=
ID NER tID POS令牌重新参数关系
1 B-ORG 1 NNP大学组织位于ARG1 ORG1-ORG1-B中
ARG1中OrgBased_的1 I-Org1 IN
1 I-ORG 1 NNP华盛顿OrgBased_In-ARG1 OrgBased_In-ARG1-I
1 I-ORG 1 NNP地震学OrgBased_In-ARG1 OrgBased_In-ARG1-I
1 L-ORG 1 NNP实验室OrgBased_在ARG1 OrgBased_在ARG1-L中
ARG2-ARG2-U中的1 U-LOC 22 NNP清洗机
然而,我将新数据输入到DF中,DF有多个条目,因此列
R
中有更多标签

DF_2=
ID NER tID POS令牌R
1 B-ORG 1 NNP大学“华盛顿大学地震学实验室*华盛顿大学”,为chris jonientz trisler*华盛顿大学地震学实验室工作。”
1 I-Org1 IN“华盛顿大学地震实验室*wash”,为chris jonientz trisler*华盛顿大学地震实验室工作。”
1 I-ORG 1 NNP华盛顿“OrgBased_位于+华盛顿大学地震学实验室*,华盛顿大学地震学实验室为+chris jonientz trisler*工作。”
1 I-ORG 1 NNP地震学“华盛顿大学地震学实验室*华盛顿大学地震学实验室*,为+克里斯·乔尼恩茨·特里斯勒*华盛顿大学地震学实验室工作。”
1 L-ORG 1 NNP实验室“位于+华盛顿大学地震实验室*华盛顿”,为+克里斯·乔尼恩茨·特里斯勒*华盛顿大学地震实验室工作。”
1 U-LOC 22 NNP wash“位于+华盛顿大学地震实验室*wash”,为+chris jonientz trisler*华盛顿大学地震实验室工作。”
1 B-Peop 25 NNP chris”,为+chris jonientz trisler*华盛顿大学地震实验室工作
1 L-Peop 25 NNP jonientz trisler”,为+chris jonientz trisler*华盛顿大学地震实验室工作
如您所见,结构是相同的,其中“,”是这两部分的分隔符。数据在列
R
中也可能包含2个以上的条目。我的代码无法意识到这是两种不同的关系,因此结果是错误的

DF_2_=
ID NER tID POS令牌重新参数关系
1个B-ORG 1个NNP大学组织位于,为ARG1工作,为ARG2组织位于-ARG1-B,为-ARG2-B工作
1 I-ORG 1 IN的OrgBased_IN,为ARG1工作,为ARG2 OrgBased_IN-ARG1-I,为-ARG2-I工作
1 I-ORG 1 NNP华盛顿OrgBased_In,为ARG1工作,ARG2 OrgBased_In-ARG1-I,为-ARG2-I工作
1 I-ORG 1 NNP地震学组织为ARG1工作,ARG2 ORG为ARG1-I工作,ARG2-ARG2-I工作
1 L-ORG 1 NNP实验室OrgBased_In,为ARG1工作,ARG2 OrgBased_In-ARG1-L,为-ARG2-L工作
ARG2-ARG2-U中的1 U-LOC 22 NNP清洗机
1 B-Peop25 NNP chris Work_For ARG1工作_For-ARG1-B
1 L-Peop25 NNP jonientz trisler工作组用于ARG1工作组用于ARG1-L
我学到的是:

DF_2_Got=
ID NER tID POS令牌重新参数关系
1 B-ORG 1 NNP大学组织位于ARG1 ORG1-ORG1-B中
ARG1中OrgBased_的1 I-Org1 IN
1 I-ORG 1 NNP华盛顿OrgBased_In-ARG1 OrgBased_In-ARG1-I
1 I-ORG 1 NNP地震学OrgBased_In-ARG1 OrgBased_In-ARG1-I
1 L-ORG 1 NNP实验室OrgBased_在ARG1 OrgBased_在ARG1-L中
ARG2-ARG2-U中的1 U-LOC 22 NNP清洗机
1 B-Peop25 NNP chris Work_For ARG1工作_For-ARG1-B
1 L-Peop25 NNP jonientz trisler工作组用于ARG1工作组用于ARG1-L
我无法更改代码以获得预期的输出。我需要做什么?有什么想法吗


编辑:根据分隔符“,”拆分行是否明智?

有了这些问题,最好从输入字符串开始,用纯Python创建一个函数来应用转换格式。Pandas基于字符串的方法也不是特别有效,因此您可能会选择从不将算法泛化

我们举几个例子:

a = 'OrgBased_In+university of washington seismology lab.*wash",,Work_For+chris jonientz-trisler*university of washington seismology lab.'
b = ',Work_For+chris jonientz-trisler*university of washington seismology lab.'
您可以使用
str.strip
str.split
来定义一个函数,将这些函数进行常规拆分

def splitter(x):
    return [i.split('+')[0] for i in x.strip(',').split(',,')]

print(splitter(a))
['OrgBased_In', 'Work_For']

print(splitter(b))
['Work_For']
然后,您可以将拆分器函数用于
pd.Series.apply
,然后是列表理解。Python 3.6+中提供的格式化字符串文本(f字符串)在这里很有用

df = pd.DataFrame({'NER': ['B-ORG', 'B-Peop25'],
                   'Relations': [a, b]})

df['Relations'] = df['Relations'].apply(splitter)

df['Relations'] = [', '.join([f'{k}-ARG{idx}-{j.split("-")[0]}' \
                              for idx, k in enumerate(i, 1)]) \
                   for i, j in zip(df['Relations'], df['NER'])]

print(df)

        NER                            Relations
0     B-ORG  OrgBased_In-ARG1-B, Work_For-ARG2-B
1  B-Peop25                      Work_For-ARG1-B
请注意,我们省略了一个系列的创建,该系列表示存在多少个参数。为此,您可以在内部列表理解中使用
枚举


如果您没有使用Python3.6+,那么可以将f字符串替换为
s
'{0}-ARG{1}-{2}'.format(k, idx, j.split('-')[0])
a = 'OrgBased_In+university of washington seismology lab.*wash",,Work_For+chris jonientz-trisler*university of washington seismology lab.'
b = ',Work_For+chris jonientz-trisler*university of washington seismology lab.'
c = ['university', 'of', 'washington', 'seismology', 'lab', 'wash', 'chris']

df = pd.DataFrame({'NER': ['B-ORG', 'I-ORG', 'I-ORG', 'I-ORG', 'I-ORG', 'U-LOC', 'B-PEOP'],
               'R': [a, a, a, a, a, a, b], 'token' : c})

def function(df):
    temp = list(filter(None, re.split(',', df[1])))
    temp1 = temp.copy()
    for i, x in enumerate(temp1):
        if df[2] not in re.split(r'[ `\=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]', x):
            del temp[i]
    relations = [x.split('+')[0] for x in temp]
    temp2 = ['-ARG2' if df[2] in x.split('*')[1] else '-ARG1' for x in temp]
    output = []
    for i in range(len(relations)):
        output.append(relations[i] + temp2[i] + '-' + df[0][0])

    return ", ".join(output)

df['Relations'] = df.apply(function, axis = 1)
df.Relations
0    OrgBased_In-ARG1-B, Work_For-ARG2-B
1    OrgBased_In-ARG1-I, Work_For-ARG2-I
2    OrgBased_In-ARG1-I, Work_For-ARG2-I
3    OrgBased_In-ARG1-I, Work_For-ARG2-I
4    OrgBased_In-ARG1-I, Work_For-ARG2-I
5                     OrgBased_In-ARG2-U
6                        Work_For-ARG1-B