簡體   English   中英

在pandas數據框中插入新行

[英]Insert new rows in pandas dataframe

我已經解析了一個包含一些詞性標記文本的xml文件,由於該文件不是完美的,所以我將數據添加到pandas數據框中,以便稍后對其進行清理。

此時,我將需要根據某些值復制一些行,並僅在復制的行和原始行中修改一個或兩個值。

實際的數據框如下所示:

In [8]: df.head()
Out[8]: 
      text     lemma       pos markintext  doublemma  multiwordexpr nodetail
0      Per       per      epsf          0          0              0        0
1   correr   correre    vta2fp          0          0              0        0
2  miglior  migliore      a2fp          0          0              0        0
3    acque     acqua     sf1fp          0          0              0        0
4     alza    alzare  vta1ips3          0          0              0        0

現在,例如,如果multiwordexpr等於1,我想復制該行並將其插入數據庫中。 所以,我想從這里開始:

In [10]: df[df['multiwordexpr'] == 1]
Out[10]: 
          text     lemma      pos markintext  doublemma  multiwordexpr
16    dietro a  dietro a   eilksl          0          0              1  

對此:

          text     lemma      pos markintext  doublemma  multiwordexpr
16    dietro    dietro a   eilksl          0          0              1  
17    a         dietro a   eilksl          0          0              1  

這是我的代碼

#!/usr/bin/python
# -*- coding: latin-1 -*-

from lxml import etree
import locale
import sys
import os
import glob
import pandas as pd
import numpy as np
import re
from string import punctuation
import random
import unicodedata

def manage_tail(taillist):
    z = []
    for line in taillist:
        y = list(line.strip())
        for punkt in y:
            z.append(punkt)
    return z if len(z) > 0 else 0

def checkmark(text):
    pattern = re.compile("\w|'",re.UNICODE)
    if re.match(pattern,text[-1]):
        return 0
    else:
        return text[-1]

path = "~/working_corpus/"
output_path = "~/devel_output/"
f = "*.xml"

docs = [f for f in glob.glob(os.path.join(path,f))]
parser = etree.XMLParser(load_dtd= True,resolve_entities=True)

x = []
for d in docs:

    tree = etree.parse(d,parser)

    for node in [z for z in  tree.iterfind(".//LM")]:
        text = node.text.strip()
        multiwordexpr = 1 if (' ' in text.replace('  ', ' ')) else 0
        lemma = node.get('lemma')
        markintext = checkmark(text)
        pos = node.get('catg')
        doublemma = 1 if (node.getparent() is not None and node.getparent().tag == 'LM1') else 0
        nodetail = manage_tail(node.tail.splitlines()) if node.tail else None
        row = [text,lemma,pos,markintext,doublemma,multiwordexpr,nodetail]
        x.append(row)


df = pd.DataFrame(x,columns=('text','lemma','pos','markintext','doublemma','multiwordexpr','nodetail'))

我已經考慮過用這種方法來管理nodetail為true的情況(因此,並不是精確的multiwordexpr問題,但要點是相同的:如何有效地在任意位置添加行,而不是最后添加行),但我不知道如何真正有效地做到這一點。 我正在尋找一個給定一個或多個條件的函數,在選定的行下插入一定數量的重復行,並在其他列中修改一個或兩個值(在這種情況下,它將拆分文本並復制行)。

l = []
i = 0
while i < len(df):
    if (df.iloc[i,6] != 0):
        ntail = df.iloc[i,6]
        df.iloc[i,6] = 0
        i += 1
        for w in range(len(ntail)):
            line = pd.DataFrame({'text': ntail[w],
            'lemma': ntail[w],
            'pos':'NaN',
            'markintext':0,
            'doublemma':0,
            'multiwordexpr':0,
            'nodetail':0},index=[i+w], columns=('text','lemma','pos','markintext','doublemma','multiwordexpr','nodetail'))
            l.append(line)
    else:
        pass
    i += 1
    sys.stdout.write("\r%d/%d" % (i,len(df)))
    sys.stdout.flush()
print "...done extracting."

for i in range(len(l)):    
    start = int((l[i].index[0])-1)
    end = int(l[i].index[0])
    df = pd.concat([df.ix[:start], l[i], df.ix[end:]]).reset_index(drop=True)
    sys.stdout.write("\r%d/%d" % (i,len(l)))
    sys.stdout.flush()

編輯:您可以預分配df,所需的長度為len(df)+df.multiwordexpr.sum()然后可以使用.ix []設置正確的行。 您仍然必須迭代原始df並將其拆分。 那可能更快。

row = ['','','',0,0,0,0]
#calculate correct length depending on your original df
df_len = len(orig_df)+orig_df.multiwordexpr.sum()

#allocate a new df
result_df = pd.DataFrame([row for x in xrange(df_len)],
                      columns=columns)
#write to it instead appending
result_df.ix[index] = ['Per','per','epsf',0,0,0,0]

編輯結束

也許創建一個新的數據框並僅將其追加比修改原始數據框要快?

您可以在分割multiwordexpr行的同時迭代原始df並追加到新的df中。 不知道這樣做是否會更好。

import pandas as pd
columns=    ['text','lemma','pos','markintext','doublelemme','multiwordexpr','nodetail']

rows = [['Per','per','epsf',0,0,0,0],
    ['dietro a','dietro a','eilksl',0,0,1,0],
    ['Per','per','epsf',0,0,0,0]]

orig_f = pd.DataFrame(rows,columns=columns)
df = pd.DataFrame(columns=columns)


for index, row in orig_f.iterrows():
    # check for multiwordexpr
    if row[5] == 1:
        s = row.copy()
        s[0]   = row[0].split(' ')[0]     
        row[0] = row[0].split(' ')[1]        
        df = df.append(s)
        df = df.append(row)

    else:
        df = df.append(row)

df = df.reset_index(drop=True)
#there are no more multi words
df.ix[df['multiwordexpr']==1, 'multiwordexpr'] = 0

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM