2015-12-08 54 views
1

我是python的新手,我试图通过读取excel文件将参数(数据框)传递给函数并更改参数(数据框)的值。 (假设我已经导入了所有必需的文件)将python数据框传递给对象并更改数据框

我注意到python没有在这里通过引用传递参数,我最终没有对数据帧进行初始化/更改。

我读到python通过对象引用而不是通过值或引用。但是,我不需要更改相同的数据框。

的输出是:类 'pandas.core.frame.DataFrame'>

from pandas import DataFrame as df 
class Data: 
    x = df 

    @staticmethod 
    def import_File(df_name , file): 
     df_name = pd.io.excel.read_excel(file.replace('"',''), sheetname='Sheet1', header=0, skiprows=None, skip_footer=0, index_col=None, parse_cols=None, parse_dates=True, date_parser=True, na_values=None, thousands=None, convert_float=True, has_index_names=None, converters=None, engine=None) 


def inputdata(): 
    Data.import_File(Data.x,r"C:\Users\Data\try.xlsx") 
    print(Data.x) 
+0

请让我们知道,我们可以进一步帮助您解决这个问题。否则,如果您发现其中一个答复回答您的问题,请接受它。谢谢! – imp9

回答

2

在代码df是类对象。要创建一个空的数据框,你需要实例化它。 Python中的Instantiating类使用函数表示法。另外,当我们读取excel文件时,我们不需要传递默认参数。这将有助于代码看起来更干净。
另外,当我们读取excel文件时,我们不需要传递默认参数。这将有助于代码看起来更干净。

from pandas import DataFrame as df 
class Data: 
    x = df() 

    @staticmethod 
    def import_File(df_name, file): 
     df_name = pd.io.excel.read_excel(file.replace('"',''), sheetname='Sheet1') 

当传递到Data.ximport_File()df_name将是指相同的对象作为Data.x,在这种情况下是一个空数据帧。但是,如果将pd.io.excel.read_excel(file)指定为df_name,则df_name与空数据框之间的连接将中断,并且df_name现在指的是excel数据帧。 Data.x在此过程中没有发生任何变化,所以它仍然连接到空数据框对象。

更简单的方法来看到这个用绳子:

x = 'red' 
df_name = x 

我们可以打破“红色”字符串对象之间的df_name连接,形成一个新的使用对象excel`。

df_name = 'excel' 
print(x) 
'red' 

但是,Data.x有一个简单的修复方法来返回excel数据帧。

from pandas import DataFrame as df 
class Data: 
    x = df() 

    @staticmethod 
    def import_File(file): 
     Data.x = pd.io.excel.read_excel(file.replace('"',''), sheetname='Sheet1') 

def inputdata(): 
    Data.import_File(r"C:\Users\Data\try.xlsx") 
    print(Data.x) 

但是,我不建议使用staticmethods,并且应该在类中包含一个构造函数作为其他答案推荐的方法。

4

你似乎在艰难地做着很多事情。我会尽量在符合标准使用模式的同时简化它。

# Whatever imports you need 
import pandas as pd 


# Static variables and methods should generally be avoided. 
# Change class and variable names to whatever is more suitable. 
# Names should be meaningful when possible. 
class MyData: 

    # Load data in constructor. Could easily do this in another method. 
    def __init__(self, filename): 
     self.data = pd.io.excel.read_excel(filename, sheetname='Sheet1') 


def inputData(): 
    # In my experience, forward slashes work just fine on Windows. 
    # Create new MyData object using constructor 
    x = MyData('C:/Users/Data/try.xlsx') 

    # Access member variable from object 
    print(x.data) 

这里是加载方法而不是构造函数的版本。

import pandas as pd 


class MyData: 

    # Constructor 
    def __init__(self): 
     # Whatever setup you need 
     self.data = None 
     self.loaded = False 

    # Method with optional argument 
    def loadFile(self, filename, sheetname='Sheet1') 
     self.data = pd.io.excel.read_excel(filename, sheetname=sheetname) 
     self.loaded = True 


def inputData(): 
    x = MyData() 
    x.loadFile('C:/Users/Data/try.xlsx') 
    print(x.data) 

    # load some other data, using sheetname 'Sheet2' instead of default 
    y = MyData() 
    y.loadFile('C:/Users/Data/tryagain.xlsx', 'Sheet2') 
    # can also pass arguments by name in any order like this: 
    # y.loadFile(sheetname='Sheet2', filename='C:/Users/Data/tryagain.xlsx') 
    print(y.data) 

    # x and y both still exist with different data. 
    # calling x.loadFile() again with a different path will overwrite its data. 

之所以它不会在你原来的代码保存是因为分配值参数名称不会改变在Python的原始变量。你可以做的是这样的:

# Continuing from the last code block 

def loadDefault(data): 
    data.loadFile('C:/Users/Data/try.xlsx') 

def testReference(): 
    x = MyData() 
    loadDefault(x) 
    # x.data now has been loaded 
    print(x.data) 


# Another example 

def setIndex0(variable, value): 
    variable[0] = value 

def testSetIndex0(): 
    v = ['hello', 'world'] 
    setIndex0(v, 'Good morning') 
    # v[0] now equals 'Good morning' 
    print(v[0]) 

但你不能做到这一点:如果你希望能够到指定位置使用一个名称来存储值

def setString(variable, value): 
    # The only thing this changes is the value of variable inside this function. 
    variable = value 

def testSetString(): 
    v = 'Start' 
    setString(v, 'Finish') 
    # v is still 'Start' 
    print(v) 

,你可以使用带索引/键的数据结构。字典允许您使用密钥访问和存储值。

import pandas as pd 


class MyData: 

    # Constructor 
    def __init__(self): 
     # make data a dictionary 
     self.data = {} 

    # Method with optional argument 
    def loadFile(self, storename, filename, sheetname='Sheet1') 
     self.data[storename] = pd.io.excel.read_excel(filename, sheetname=sheetname) 

    # Access method 
    def getData(self, name): 
     return self.data[name] 


def inputData(): 
    x = MyData() 
    x.loadFile('name1', 'C:/Users/Data/try.xlsx') 
    x.loadFile('name2', 'C:/Users/Data/tryagain.xlsx', 'Sheet2') 

    # access Sheet1 
    print(x.getData('name1')) 

    # access Sheet2 
    print(x.getData('name2')) 

如果你真的希望函数是静态的,那么你根本不需要创建一个新类。创建类的主要原因是将其用作可重复使用的结构,以便使用特定于该数据的方法保存数据。

import pandas as pd 

# wrap read_excel to make it easier to use 
def loadFile(filename, sheetname='Sheet1'): 
    return pd.io.excel.read_excel(filename, sheetname=sheetname) 

def inputData(): 
    x = loadFile('C:/Users/Data/try.xlsx') 
    print(x) 

    # the above is exactly the same as 
    x = pd.io.excel.read_excel('C:/Users/Data/try.xlsx', sheetname='Sheet1') 
    print(x) 
+0

感谢您的回答。但是,我一直在考虑在一个类中存在多个数据帧属性的情况。说,X,Y,Z和我想有一个简单的方法来实例化每个与一个方法获取他们的名字和导入文件。想象一下,我们有多个数据框可以加载到一个类对象中。我使用静态,因为加载一个Excel文件似乎不是特定于类对象。 –

+1

我添加了更多的示例,希望他们解决在一个对象中如何使用可变数量的数据框以及如何使用函数而不是类。 – Darcinon

+0

谢谢,非常有帮助。 –