Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/354.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 按行修改数据帧中的字符串_Python_String_Pandas_Strip - Fatal编程技术网

Python 按行修改数据帧中的字符串

Python 按行修改数据帧中的字符串,python,string,pandas,strip,Python,String,Pandas,Strip,在Python3的pandas数据帧中,列string1和string2中有以下字符串: import pandas as pd datainput = [ { 'string1': 'TTTABCDABCDTTTTT', 'string2': 'ABABABABABABABAA' }, { 'string1': 'AAAAAAAA', 'string2': 'TTAAAATT' }, { 'string1': 'TTABCDTTTTT', 'string2': 'AB

在Python3的pandas数据帧中,列
string1
string2
中有以下字符串:

import pandas as pd

datainput = [
    { 'string1': 'TTTABCDABCDTTTTT', 'string2': 'ABABABABABABABAA' },
    { 'string1': 'AAAAAAAA', 'string2': 'TTAAAATT' },
    { 'string1': 'TTABCDTTTTT', 'string2': 'ABABABABABA' }
]

df = pd.DataFrame(datainput)

df
            string1           string2
0  TTTABCDABCDTTTTT  ABABABABABABABAA
1          AAAAAAAA          TTAAAATT
2       TTABCDTTTTT       ABABABABABA
对于每一行,列
string1
string2
中的字符串定义为相同的长度

对于数据帧的每一行,字符串可能需要“清理”开头/结尾字母“T”。但是,对于每一行,字符串都需要去除相同数量的字符,以便字符串保持相同的长度

正确的输出如下所示:

df
            string1           string2
0          ABCDABCD      BABABABA
1          AAAA          AAAA
2          ABCD          ABAB
如果这是两个变量,则可以直接使用
strip()
,例如

string1 = "TTTABCDABCDTTTTT"
string2 = "ABABABABABABABAA"

length_original = len(string1)
num_left_chars = len(string1) - len(string1.lstrip('T'))
num_right_chars = len(string1.rstrip('T'))
edited = string1[num_left_chars:num_right_chars]
## print(edited)
## 'ABCDABCD'
但是,在这种情况下,需要遍历所有行并同时重新定义两行。如何逐行修改这些字符串

编辑:我的主要困惑是,鉴于两列都可能
T
,我如何重新定义它们

raw_data = {'name': ['Will Morris', 'Alferd Hitcock', 'Sir William', 'Daniel Thomas'],
                'age': [11, 49, 66, 77],
                'color': ['TblueT', 'redT', 'white', "cyan"],
                'marks': [74, 90, 44, 17]}
df = pd.DataFrame(raw_data, columns = ['name', 'age', 'color', 'grade'])
print(df)
cols =  ['name','color']
print("new df")
#following line does the magic 

df[cols] = df[cols].apply(lambda row: row.str.lstrip('T').str.rstrip('T'), axis=1)
print(df)
将打印

               name  age   color  grade
0  TWillard MorrisT   20  TblueT     88
1       Al Jennings   19    redT     92
2      Omar Mullins   22  yellow     95
3  Spencer McDaniel   21   green     70

new df

               name  age   color  grade
0    Willard Morris   20    blue     88
1       Al Jennings   19     red     92
2      Omar Mullins   22  yellow     95
3  Spencer McDaniel   21   green     70

有点长,但能完成任务

import re
def count_head(s):
    head = re.findall('^T+', s)
    if head:
        return len(head[0])
    return 0
def count_tail(s):
    tail = re.findall('T+$', s)
    if tail:
        return len(tail[0])
    return 0
df1 = df.copy()
df1['st1_head'] = df1['string1'].apply(count_head)
df1['st2_head'] = df1['string2'].apply(count_head)
df1['st1_tail'] = df1['string1'].apply(count_tail)
df1['st2_tail'] = df1['string2'].apply(count_tail)
df1['length'] = df1['string1'].str.len()

def trim_strings(row):
    head = max(row['st1_head'], row['st2_head'])
    tail = max(row['st1_tail'], row['st2_tail'])
    l = row['length']
    return {'string1': row['string1'][head:(l-tail)],
           'string2': row['string2'][head:(l-tail)]}
new_df = pd.DataFrame(list(df1.apply(trim_strings, axis=1)))
print(new_df)
输出:

    string1   string2
0  ABCDABCD  BABABABA
1      AAAA      AAAA
2      ABCD      ABAB
更紧凑的版本:

def trim(st1, st2):
    l = len(st1)
    head = max(len(st1) - len(st1.lstrip('T')), 
              len(st2) - len(st2.lstrip('T')))
    tail = max(len(st1) - len(st1.rstrip('T')), 
              len(st2) - len(st2.rstrip('T')))
    return (st1[head:(l-tail)],
           st2[head:(l-tail)])

new_df = pd.DataFrame(list(
    df.apply(lambda r: trim(r['string1'], r['string2']), 
         axis=1)), columns=['string1', 'string2'])
print(new_df)

需要注意的主要问题是
df.apply(,axis=1)
,它允许您在每一行上执行任何功能(在本例中,同时作用于两列)。

两列是否都有
T
?还是只有一个?原则上,请查看@user3483203这篇文章,两个专栏都可以。但是,它主要是
string1
T
的第一列,谢谢您的帮助。但是我需要修改这两个列,因为这两个列都可能有
T
@ShanZhengYang我现在已经更改了代码,它可以按预期工作。请把答案标记为正确。我想还是有点混乱——我很乐意编辑我的问题。两列中的字符串长度相等。如果删除一个字符串中的N个字符,则必须删除另一个字符串中的N个字符。我写原始答案时非常困。我不太确定是否有一个简单的方法来做到这一点。如果你正在寻找黑客,Yoshi Hammer写的答案应该有用。我会尽快给你一个更好的版本。谢谢!如果你能得到更有效/更快的帮助,我将不胜感激。这是非常明智的,回答了我的问题。我们为每个字符串的计数创建一个新列,然后使用它来操作新列。