繁体   English   中英

从数据框列中拆分带数字的字符串并将其转换为浮点型

[英]Splitting a mixed number string from a dataframe column and converting it to a float

我有一个数据框,其中有一列字符串是整数和混合分数的混合。 我想将列“ y”转换为浮点数。

x            y         z
0            4      Info
1        8 1/2      Info
2          3/4      Info
3           10      Info
4            4      Info
5        6 1/4      Info

我正在考虑的逻辑是将列“ y”除以“”和“ /”,以创建三个单独的列,如下所示。

x         base        b        c         z
0            4        0        0      Info
1            8        1        2      Info
2            0        3        4      Info
3           10        0        0      Info
4            4        0        0      Info
5            6        1        4      Info

从这里我可以

def convertReplace(df):
    convert = lambda x: float(x)
    df['base'].apply(convert)
    df['b'].apply(convert)
    df['c'].apply(convert)
    decimal = lambda x,y: x/y        
    try:
        df['d'] = decimal(df['b'],df['c'])
        df['y'] = df['base'] + df['d']
    except:
        df['y'] = df['base']
    return df

这可能行得通,但是我无法使用此处找到的方法来拆分列。

df = pd.DataFrame(df.y.str.split(' ',1).str.split('/',1).tolist(),columns = ['base','b','c'])

该错误表明,每次可能为1、2或3时,它都希望有3个参数。即使此线程也没有使用多个分隔符。

实际的数据帧有超过40万行。 效率会很棒,但我对完成它更感兴趣。 这种逻辑是正确的还是有更简洁的方法来做到这一点? 任何帮助表示赞赏。

您可以尝试分数模块。 这里是单线:

import fractions
df['y_float'] = df['y'].apply(lambda frac: float(sum([fractions.Fraction(x) for x in frac.split()])))

这给出:

       y     z  y_float
0      4  Info     4.00
1  8 1/2  Info     8.50
2    3/4  Info     0.75
3     10  Info    10.00
4      4  Info     4.00
5  6 1/4  Info     6.25

[编辑]修正版本,排除了负分数以及无效文本:

我意识到上述方法不适用于负分数,因此这里考虑了这一点。 事实证明,为此一线是非常棘手的!

def get_sign(num_str):
    """
    Verify the sign of the fraction
    """
    return 1-2*num_str.startswith('-')

def is_valid_fraction(text_str):
    """
    Check if the string provided is a valid fraction.
    Here I just used a quick example to check for something of the form of the fraction you have. For something more robust based on what your data can potentially contain, a regex approach would be better.
    """
    return text_str.replace(' ', '').replace('-', '').replace('/', '').isdigit()

def convert_to_float(text_str):
    """
    Convert an incoming string to a float if it is a fraction
    """
     if is_valid_fraction(text_str):
         sgn = get_sign(text_str)
         return sgn*float(sum([abs(fractions.Fraction(x)) for x in text_str.split()]))
     else:
         return pd.np.nan # Insert a NaN if it is invalid text

所以现在您将拥有:

>>> df['y_float'] = df['y'].apply(lambda frac: convert_to_float(frac))
>>> df
              y     z  y_float
0             4  Info     4.00
1         8 1/2  Info     8.50
2           3/4  Info     0.75
3            10  Info    10.00
4             0  Info     0.00
5         6 1/4  Info     6.25
6        -3 2/5  Info    -3.40
7          -4/5  Info    -0.80
8  gibberish100  Info      NaN

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM