Python 如何组合DataFame列数据和固定文本字符串

Python 如何组合DataFame列数据和固定文本字符串,python,pandas,dataframe,concatenation,Python,Pandas,Dataframe,Concatenation,我想在一个更大的数据框中组合4列和一个自定义(空格)分隔符(我已经用下面的代码完成了),但是我想在每个连接的开始和结束处添加一个固定的字符串。 这些列是X&Y坐标对,但出于这个目的,它们可以作为str处理(一旦我修剪到小数点后3位) 我在这个网站上找到了很多连接列的选项,但是没有一个可以连接列和一个一致的固定字符串。对于我来说,最懒的方法就是再创建两个DataFrame列,一个用于开始,一个用于结束,然后单击所有内容。有更复杂的方法吗 import pandas as pd from panda

我想在一个更大的数据框中组合4列和一个自定义(空格)分隔符(我已经用下面的代码完成了),但是我想在每个连接的开始和结束处添加一个固定的字符串。 这些列是X&Y坐标对,但出于这个目的,它们可以作为str处理(一旦我修剪到小数点后3位)

我在这个网站上找到了很多连接列的选项,但是没有一个可以连接列和一个一致的固定字符串。对于我来说,最懒的方法就是再创建两个DataFrame列,一个用于开始,一个用于结束,然后单击所有内容。有更复杂的方法吗

import pandas as pd
from pandas import DataFrame
import numpy as np

def str_join(df, sep, *cols):
    from functools import reduce
    return reduce (lambda x,y: x.astype(str).str.cat(y.astype(str), sep=sep),
                   [df[col] for col in cols])

data= pd.read_csv('/Users/XXXXXX/Desktop/Lines.csv')
df=pd.DataFrame(data, columns=['Name','SOLE','SOLN','EOLE','EOLN','EOLKP','Wind','Wave']) 

df['SOLE']=round(df['SOLE'],3)
df['SOLN']=round(df['SOLN'],3)
df['EOLE']=round(df['EOLE'],3)
df['EOLN']=round(df['EOLN'],3)

df['WKT']=str_join(df,' ','SOLE','SOLN','EOLE','EOLN')

df.to_csv('OutLine.csv') #turn on to create output file
这给了我很多

WKT
476912.131 6670122.285 470329.949 6676260.271
我要做的是在每个连接的开头添加“(LINESTRING”并在每个连接的结尾添加“)”,以提供给我

WKT
(LINESTRING 476912.131 6670122.285 470329.949 6676260.271 )

您的功能已经很好了,只需添加几项:

def str_连接(df、sep、*cols):
#所有列必须是数字才能使用df[col].round(3)
从functools导入reduce
返回reduce(lambda x,y:'LINESTRING'+x.astype(str).str.cat(y.astype(str)+'),sep=sep),
[df[col]。四舍五入(3)为col中的col])
这样使用它

df['new']='LINESTRING'
df['WKT']=pd.concat([df['new'],df['SOLE'],df['SOLN'],df['EOLE'],df['EOLN']])

您还可以创建要导出的列的集合,执行快速数据类型格式,并应用联接

target_cols = ['SOLE','SOLN','EOLE','EOLN',]


# Make sure to use along axis 1 (columns) because default is 0
# Also, if you're on Python 3.6+, I think you can use f-strings to format your floats.
df['WKT'] = df[target_cols].apply(lambda x: '(LINESTRING ' + ' '.join(f"{i:.3f}" for i in x) + ')', axis=1)
结果:

In [0]: df.iloc[:,-3:]

Out [0]:
        Wind   Wave                                                WKT
    0  wind1  wave1  (LINESTRING 476912.131 6670122.285 470329.949 ...
**对不起,我用的是Spyder,它是一个终端输出的守财奴。这是“WKT”的打印件

In [1]: print(df['WKT'].values)
Out [1]: ['(LINESTRING 476912.131 6670122.285 470329.949 6676260.271)']
***编辑:要在“SOLN”后添加逗号,我们可以使用另一种方法:

target_cols = ['SOLE','SOLN','EOLE','EOLN',]

# Format strings in advance
# Set comma_col to our desired column name. This could also be a tuple for multiple names, then replace `==` with `in` in the loop below.

comma_col = 'SOLN'


# To find the last column, which doesn't need a space here, we just select the last value from our list.  I did it this way in case our list order doesn't match the dataframe order.

last_col = df[target_cols].columns.values.tolist()[-1]


# Traditional if-then method
for col in df[target_cols]:
    if col == comma_col:
        df[col] = df[col].apply(lambda x: f"{x:.3f}" + ",") # Explicit comma
    elif col == last_col:
        df[col] = df[col].apply(lambda x: f"{x:.3f}")
    else:
        df[col] = df[col].apply(lambda x: f"{x:.3f}" + " ") # Explicit whitespace

# Adding our 'WKT' column as before, but the .join() portion doesn't have a space in it now.
df['WKT'] = df[target_cols].apply(lambda x: '(LINESTRING ' + ''.join(i for i in x) + ')', axis=1)
最后:

In [0]: print(df['WKT'][0])
Out [0]: (LINESTRING 476912.131 6670122.286,470329.950 6676260.271)

说到这里,我回答了我的问题,试图将数据加载到我的GIS系统中,我意识到我错过了一件事。我需要在SOLN和EOLE之间添加一个“逗号”,而不是一个“空格”。(行字符串476912.131 6670122.285470329.949 6676260.271)为什么使用
.values
?据我所知,这两种用法都是不必要的。@AtlanticWorker好的,它调整了它。我不知道您是否希望在最后一个浮点之后(括号之前)有一个空格,但如果您希望包含空格,可以对其进行调整。@MarkMoretto,Success,输出现在加载到我的GIS包中。我现在坐下来,了解一下它是如何工作的。你为什么要这样格式化数据?我正在将它导入QGIS。要使其识别具有起点(鞋底、鞋底)和终点(下线、下线)的线条,需要4个数据点。我想在两个XY对之间使用LINESTRING作为前缀和逗号。你说的是哪对?我没有看到任何逗号。